1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2018-2019, Linaro Limited 4 */ 5 6 #include <assert.h> 7 #include <crypto/crypto.h> 8 #include <kernel/handle.h> 9 #include <kernel/huk_subkey.h> 10 #include <kernel/misc.h> 11 #include <kernel/msg_param.h> 12 #include <kernel/pseudo_ta.h> 13 #include <kernel/user_ta.h> 14 #include <kernel/user_ta_store.h> 15 #include <ldelf.h> 16 #include <mm/file.h> 17 #include <mm/fobj.h> 18 #include <mm/tee_mmu.h> 19 #include <pta_system.h> 20 #include <string.h> 21 #include <tee_api_defines_extensions.h> 22 #include <tee_api_defines.h> 23 #include <util.h> 24 #include <kernel/tpm.h> 25 26 #define MAX_ENTROPY_IN 32u 27 28 struct bin_handle { 29 const struct user_ta_store_ops *op; 30 struct user_ta_store_handle *h; 31 struct file *f; 32 size_t offs_bytes; 33 size_t size_bytes; 34 }; 35 36 struct system_ctx { 37 struct handle_db db; 38 const struct user_ta_store_ops *store_op; 39 }; 40 41 static unsigned int system_pnum; 42 43 static TEE_Result system_rng_reseed(struct tee_ta_session *s __unused, 44 uint32_t param_types, 45 TEE_Param params[TEE_NUM_PARAMS]) 46 { 47 size_t entropy_sz; 48 uint8_t *entropy_input; 49 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 50 TEE_PARAM_TYPE_NONE, 51 TEE_PARAM_TYPE_NONE, 52 TEE_PARAM_TYPE_NONE); 53 54 if (exp_pt != param_types) 55 return TEE_ERROR_BAD_PARAMETERS; 56 entropy_input = params[0].memref.buffer; 57 entropy_sz = params[0].memref.size; 58 59 /* Fortuna PRNG requires seed <= 32 bytes */ 60 if (!entropy_sz) 61 return TEE_ERROR_BAD_PARAMETERS; 62 63 entropy_sz = MIN(entropy_sz, MAX_ENTROPY_IN); 64 65 crypto_rng_add_event(CRYPTO_RNG_SRC_NONSECURE, &system_pnum, 66 entropy_input, entropy_sz); 67 return TEE_SUCCESS; 68 } 69 70 static TEE_Result system_derive_ta_unique_key(struct tee_ta_session *s, 71 uint32_t param_types, 72 TEE_Param params[TEE_NUM_PARAMS]) 73 { 74 size_t data_len = sizeof(TEE_UUID); 75 TEE_Result res = TEE_ERROR_GENERIC; 76 uint8_t *data = NULL; 77 uint32_t access_flags = 0; 78 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 79 TEE_PARAM_TYPE_MEMREF_OUTPUT, 80 TEE_PARAM_TYPE_NONE, 81 TEE_PARAM_TYPE_NONE); 82 struct user_ta_ctx *utc = NULL; 83 84 if (exp_pt != param_types) 85 return TEE_ERROR_BAD_PARAMETERS; 86 87 if (params[0].memref.size > TA_DERIVED_EXTRA_DATA_MAX_SIZE || 88 params[1].memref.size < TA_DERIVED_KEY_MIN_SIZE || 89 params[1].memref.size > TA_DERIVED_KEY_MAX_SIZE) 90 return TEE_ERROR_BAD_PARAMETERS; 91 92 utc = to_user_ta_ctx(s->ctx); 93 94 /* 95 * The derived key shall not end up in non-secure memory by 96 * mistake. 97 * 98 * Note that we're allowing shared memory as long as it's 99 * secure. This is needed because a TA always uses shared memory 100 * when communicating with another TA. 101 */ 102 access_flags = TEE_MEMORY_ACCESS_WRITE | TEE_MEMORY_ACCESS_ANY_OWNER | 103 TEE_MEMORY_ACCESS_SECURE; 104 res = tee_mmu_check_access_rights(&utc->uctx, access_flags, 105 (uaddr_t)params[1].memref.buffer, 106 params[1].memref.size); 107 if (res != TEE_SUCCESS) 108 return TEE_ERROR_SECURITY; 109 110 /* Take extra data into account. */ 111 if (ADD_OVERFLOW(data_len, params[0].memref.size, &data_len)) 112 return TEE_ERROR_SECURITY; 113 114 data = calloc(data_len, 1); 115 if (!data) 116 return TEE_ERROR_OUT_OF_MEMORY; 117 118 memcpy(data, &s->ctx->uuid, sizeof(TEE_UUID)); 119 120 /* Append the user provided data */ 121 memcpy(data + sizeof(TEE_UUID), params[0].memref.buffer, 122 params[0].memref.size); 123 124 res = huk_subkey_derive(HUK_SUBKEY_UNIQUE_TA, data, data_len, 125 params[1].memref.buffer, 126 params[1].memref.size); 127 free(data); 128 129 return res; 130 } 131 132 static TEE_Result system_map_zi(struct tee_ta_session *s, uint32_t param_types, 133 TEE_Param params[TEE_NUM_PARAMS]) 134 { 135 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 136 TEE_PARAM_TYPE_VALUE_INOUT, 137 TEE_PARAM_TYPE_VALUE_INPUT, 138 TEE_PARAM_TYPE_NONE); 139 struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx); 140 uint32_t prot = TEE_MATTR_URW | TEE_MATTR_PRW; 141 TEE_Result res = TEE_ERROR_GENERIC; 142 struct mobj *mobj = NULL; 143 uint32_t pad_begin = 0; 144 uint32_t vm_flags = 0; 145 struct fobj *f = NULL; 146 uint32_t pad_end = 0; 147 size_t num_bytes = 0; 148 vaddr_t va = 0; 149 150 if (exp_pt != param_types) 151 return TEE_ERROR_BAD_PARAMETERS; 152 if (params[0].value.b & ~PTA_SYSTEM_MAP_FLAG_SHAREABLE) 153 return TEE_ERROR_BAD_PARAMETERS; 154 155 if (params[0].value.b & PTA_SYSTEM_MAP_FLAG_SHAREABLE) 156 vm_flags |= VM_FLAG_SHAREABLE; 157 158 num_bytes = params[0].value.a; 159 va = reg_pair_to_64(params[1].value.a, params[1].value.b); 160 pad_begin = params[2].value.a; 161 pad_end = params[2].value.b; 162 163 f = fobj_ta_mem_alloc(ROUNDUP(num_bytes, SMALL_PAGE_SIZE) / 164 SMALL_PAGE_SIZE); 165 if (!f) 166 return TEE_ERROR_OUT_OF_MEMORY; 167 mobj = mobj_with_fobj_alloc(f, NULL); 168 fobj_put(f); 169 if (!mobj) 170 return TEE_ERROR_OUT_OF_MEMORY; 171 res = vm_map_pad(&utc->uctx, &va, num_bytes, prot, vm_flags, 172 mobj, 0, pad_begin, pad_end); 173 mobj_put(mobj); 174 if (!res) 175 reg_pair_from_64(va, ¶ms[1].value.a, ¶ms[1].value.b); 176 177 return res; 178 } 179 180 static TEE_Result system_unmap(struct tee_ta_session *s, uint32_t param_types, 181 TEE_Param params[TEE_NUM_PARAMS]) 182 { 183 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 184 TEE_PARAM_TYPE_VALUE_INPUT, 185 TEE_PARAM_TYPE_NONE, 186 TEE_PARAM_TYPE_NONE); 187 struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx); 188 TEE_Result res = TEE_SUCCESS; 189 uint32_t vm_flags = 0; 190 vaddr_t va = 0; 191 size_t sz = 0; 192 193 if (exp_pt != param_types) 194 return TEE_ERROR_BAD_PARAMETERS; 195 196 if (params[0].value.b) 197 return TEE_ERROR_BAD_PARAMETERS; 198 199 va = reg_pair_to_64(params[1].value.a, params[1].value.b); 200 sz = ROUNDUP(params[0].value.a, SMALL_PAGE_SIZE); 201 202 res = vm_get_flags(&utc->uctx, va, sz, &vm_flags); 203 if (res) 204 return res; 205 if (vm_flags & VM_FLAG_PERMANENT) 206 return TEE_ERROR_ACCESS_DENIED; 207 208 return vm_unmap(&to_user_ta_ctx(s->ctx)->uctx, va, sz); 209 } 210 211 static void ta_bin_close(void *ptr) 212 { 213 struct bin_handle *binh = ptr; 214 215 if (binh) { 216 if (binh->op && binh->h) 217 binh->op->close(binh->h); 218 file_put(binh->f); 219 } 220 free(binh); 221 } 222 223 static TEE_Result system_open_ta_binary(struct system_ctx *ctx, 224 uint32_t param_types, 225 TEE_Param params[TEE_NUM_PARAMS]) 226 { 227 TEE_Result res = TEE_SUCCESS; 228 struct bin_handle *binh = NULL; 229 int h = 0; 230 TEE_UUID *uuid = NULL; 231 uint8_t tag[FILE_TAG_SIZE] = { 0 }; 232 unsigned int tag_len = sizeof(tag); 233 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 234 TEE_PARAM_TYPE_VALUE_OUTPUT, 235 TEE_PARAM_TYPE_NONE, 236 TEE_PARAM_TYPE_NONE); 237 238 if (exp_pt != param_types) 239 return TEE_ERROR_BAD_PARAMETERS; 240 if (params[0].memref.size != sizeof(*uuid)) 241 return TEE_ERROR_BAD_PARAMETERS; 242 243 uuid = params[0].memref.buffer; 244 245 binh = calloc(1, sizeof(*binh)); 246 if (!binh) 247 return TEE_ERROR_OUT_OF_MEMORY; 248 249 SCATTERED_ARRAY_FOREACH(binh->op, ta_stores, struct user_ta_store_ops) { 250 DMSG("Lookup user TA ELF %pUl (%s)", 251 (void *)uuid, binh->op->description); 252 253 res = binh->op->open(uuid, &binh->h); 254 DMSG("res=0x%x", res); 255 if (res != TEE_ERROR_ITEM_NOT_FOUND && 256 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 257 break; 258 } 259 if (res) 260 goto err; 261 262 res = binh->op->get_size(binh->h, &binh->size_bytes); 263 if (res) 264 goto err; 265 res = binh->op->get_tag(binh->h, tag, &tag_len); 266 if (res) 267 goto err; 268 binh->f = file_get_by_tag(tag, tag_len); 269 if (!binh->f) 270 goto err_oom; 271 272 h = handle_get(&ctx->db, binh); 273 if (h < 0) 274 goto err_oom; 275 276 return TEE_SUCCESS; 277 err_oom: 278 res = TEE_ERROR_OUT_OF_MEMORY; 279 err: 280 ta_bin_close(binh); 281 return res; 282 } 283 284 static TEE_Result system_close_ta_binary(struct system_ctx *ctx, 285 uint32_t param_types, 286 TEE_Param params[TEE_NUM_PARAMS]) 287 { 288 TEE_Result res = TEE_SUCCESS; 289 struct bin_handle *binh = NULL; 290 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 291 TEE_PARAM_TYPE_NONE, 292 TEE_PARAM_TYPE_NONE, 293 TEE_PARAM_TYPE_NONE); 294 295 if (exp_pt != param_types) 296 return TEE_ERROR_BAD_PARAMETERS; 297 298 if (params[0].value.b) 299 return TEE_ERROR_BAD_PARAMETERS; 300 301 binh = handle_put(&ctx->db, params[0].value.a); 302 if (!binh) 303 return TEE_ERROR_BAD_PARAMETERS; 304 305 if (binh->offs_bytes < binh->size_bytes) 306 res = binh->op->read(binh->h, NULL, 307 binh->size_bytes - binh->offs_bytes); 308 309 ta_bin_close(binh); 310 return res; 311 } 312 313 static TEE_Result binh_copy_to(struct bin_handle *binh, vaddr_t va, 314 size_t offs_bytes, size_t num_bytes) 315 { 316 TEE_Result res = TEE_SUCCESS; 317 size_t l = num_bytes; 318 319 if (offs_bytes < binh->offs_bytes) 320 return TEE_ERROR_BAD_STATE; 321 if (offs_bytes > binh->offs_bytes) { 322 res = binh->op->read(binh->h, NULL, 323 offs_bytes - binh->offs_bytes); 324 if (res) 325 return res; 326 binh->offs_bytes = offs_bytes; 327 } 328 329 if (binh->offs_bytes + l > binh->size_bytes) { 330 size_t rb = binh->size_bytes - binh->offs_bytes; 331 332 res = binh->op->read(binh->h, (void *)va, rb); 333 if (res) 334 return res; 335 memset((uint8_t *)va + rb, 0, l - rb); 336 binh->offs_bytes = binh->size_bytes; 337 } else { 338 res = binh->op->read(binh->h, (void *)va, l); 339 if (res) 340 return res; 341 binh->offs_bytes += l; 342 } 343 344 return TEE_SUCCESS; 345 } 346 347 static TEE_Result system_map_ta_binary(struct system_ctx *ctx, 348 struct tee_ta_session *s, 349 uint32_t param_types, 350 TEE_Param params[TEE_NUM_PARAMS]) 351 { 352 const uint32_t accept_flags = PTA_SYSTEM_MAP_FLAG_SHAREABLE | 353 PTA_SYSTEM_MAP_FLAG_WRITEABLE | 354 PTA_SYSTEM_MAP_FLAG_EXECUTABLE; 355 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 356 TEE_PARAM_TYPE_VALUE_INPUT, 357 TEE_PARAM_TYPE_VALUE_INOUT, 358 TEE_PARAM_TYPE_VALUE_INPUT); 359 struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx); 360 struct bin_handle *binh = NULL; 361 TEE_Result res = TEE_SUCCESS; 362 struct file_slice *fs = NULL; 363 bool file_is_locked = false; 364 struct mobj *mobj = NULL; 365 uint32_t offs_bytes = 0; 366 uint32_t offs_pages = 0; 367 uint32_t num_bytes = 0; 368 uint32_t pad_begin = 0; 369 uint32_t pad_end = 0; 370 size_t num_pages = 0; 371 uint32_t flags = 0; 372 uint32_t prot = 0; 373 vaddr_t va = 0; 374 375 if (exp_pt != param_types) 376 return TEE_ERROR_BAD_PARAMETERS; 377 378 binh = handle_lookup(&ctx->db, params[0].value.a); 379 if (!binh) 380 return TEE_ERROR_BAD_PARAMETERS; 381 flags = params[0].value.b; 382 offs_bytes = params[1].value.a; 383 num_bytes = params[1].value.b; 384 va = reg_pair_to_64(params[2].value.a, params[2].value.b); 385 pad_begin = params[3].value.a; 386 pad_end = params[3].value.b; 387 388 if ((flags & accept_flags) != flags) 389 return TEE_ERROR_BAD_PARAMETERS; 390 391 if ((flags & PTA_SYSTEM_MAP_FLAG_SHAREABLE) && 392 (flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE)) 393 return TEE_ERROR_BAD_PARAMETERS; 394 395 if ((flags & PTA_SYSTEM_MAP_FLAG_EXECUTABLE) && 396 (flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE)) 397 return TEE_ERROR_BAD_PARAMETERS; 398 399 if (offs_bytes & SMALL_PAGE_MASK) 400 return TEE_ERROR_BAD_PARAMETERS; 401 402 prot = TEE_MATTR_UR | TEE_MATTR_PR; 403 if (flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE) 404 prot |= TEE_MATTR_UW | TEE_MATTR_PW; 405 if (flags & PTA_SYSTEM_MAP_FLAG_EXECUTABLE) 406 prot |= TEE_MATTR_UX; 407 408 offs_pages = offs_bytes >> SMALL_PAGE_SHIFT; 409 num_pages = ROUNDUP(num_bytes, SMALL_PAGE_SIZE) / SMALL_PAGE_SIZE; 410 411 if (!file_trylock(binh->f)) { 412 /* 413 * Before we can block on the file lock we must make all 414 * our page tables available for reclaiming in order to 415 * avoid a dead-lock with the other thread (which already 416 * is holding the file lock) mapping lots of memory below. 417 */ 418 tee_mmu_set_ctx(NULL); 419 file_lock(binh->f); 420 tee_mmu_set_ctx(s->ctx); 421 } 422 file_is_locked = true; 423 fs = file_find_slice(binh->f, offs_pages); 424 if (fs) { 425 /* If there's registered slice it has to match */ 426 if (fs->page_offset != offs_pages || 427 num_pages > fs->fobj->num_pages) { 428 res = TEE_ERROR_BAD_PARAMETERS; 429 goto err; 430 } 431 432 /* If there's a slice we must be mapping shareable */ 433 if (!(flags & PTA_SYSTEM_MAP_FLAG_SHAREABLE)) { 434 res = TEE_ERROR_BAD_PARAMETERS; 435 goto err; 436 } 437 438 mobj = mobj_with_fobj_alloc(fs->fobj, binh->f); 439 if (!mobj) { 440 res = TEE_ERROR_OUT_OF_MEMORY; 441 goto err; 442 } 443 res = vm_map_pad(&utc->uctx, &va, num_pages * SMALL_PAGE_SIZE, 444 prot, VM_FLAG_READONLY, 445 mobj, 0, pad_begin, pad_end); 446 mobj_put(mobj); 447 if (res) 448 goto err; 449 } else { 450 struct fobj *f = fobj_ta_mem_alloc(num_pages); 451 struct file *file = NULL; 452 uint32_t vm_flags = 0; 453 454 if (!f) { 455 res = TEE_ERROR_OUT_OF_MEMORY; 456 goto err; 457 } 458 if (!(flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE)) { 459 file = binh->f; 460 vm_flags |= VM_FLAG_READONLY; 461 } 462 463 mobj = mobj_with_fobj_alloc(f, file); 464 fobj_put(f); 465 if (!mobj) { 466 res = TEE_ERROR_OUT_OF_MEMORY; 467 goto err; 468 } 469 res = vm_map_pad(&utc->uctx, &va, num_pages * SMALL_PAGE_SIZE, 470 TEE_MATTR_PRW, vm_flags, mobj, 0, 471 pad_begin, pad_end); 472 mobj_put(mobj); 473 if (res) 474 goto err; 475 res = binh_copy_to(binh, va, offs_bytes, num_bytes); 476 if (res) 477 goto err_unmap_va; 478 res = vm_set_prot(&utc->uctx, va, num_pages * SMALL_PAGE_SIZE, 479 prot); 480 if (res) 481 goto err_unmap_va; 482 483 /* 484 * The context currently is active set it again to update 485 * the mapping. 486 */ 487 tee_mmu_set_ctx(s->ctx); 488 489 if (!(flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE)) { 490 res = file_add_slice(binh->f, f, offs_pages); 491 if (res) 492 goto err_unmap_va; 493 } 494 } 495 496 file_unlock(binh->f); 497 498 reg_pair_from_64(va, ¶ms[2].value.a, ¶ms[2].value.b); 499 return TEE_SUCCESS; 500 501 err_unmap_va: 502 if (vm_unmap(&utc->uctx, va, num_pages * SMALL_PAGE_SIZE)) 503 panic(); 504 505 /* 506 * The context currently is active set it again to update 507 * the mapping. 508 */ 509 tee_mmu_set_ctx(s->ctx); 510 511 err: 512 if (file_is_locked) 513 file_unlock(binh->f); 514 515 return res; 516 } 517 518 static TEE_Result system_copy_from_ta_binary(struct system_ctx *ctx, 519 uint32_t param_types, 520 TEE_Param params[TEE_NUM_PARAMS]) 521 { 522 struct bin_handle *binh = NULL; 523 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 524 TEE_PARAM_TYPE_MEMREF_OUTPUT, 525 TEE_PARAM_TYPE_NONE, 526 TEE_PARAM_TYPE_NONE); 527 528 if (exp_pt != param_types) 529 return TEE_ERROR_BAD_PARAMETERS; 530 531 binh = handle_lookup(&ctx->db, params[0].value.a); 532 if (!binh) 533 return TEE_ERROR_BAD_PARAMETERS; 534 535 return binh_copy_to(binh, (vaddr_t)params[1].memref.buffer, 536 params[0].value.b, params[1].memref.size); 537 } 538 539 static TEE_Result system_set_prot(struct tee_ta_session *s, 540 uint32_t param_types, 541 TEE_Param params[TEE_NUM_PARAMS]) 542 { 543 const uint32_t accept_flags = PTA_SYSTEM_MAP_FLAG_WRITEABLE | 544 PTA_SYSTEM_MAP_FLAG_EXECUTABLE; 545 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 546 TEE_PARAM_TYPE_VALUE_INPUT, 547 TEE_PARAM_TYPE_NONE, 548 TEE_PARAM_TYPE_NONE); 549 struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx); 550 uint32_t prot = TEE_MATTR_UR | TEE_MATTR_PR; 551 TEE_Result res = TEE_SUCCESS; 552 uint32_t vm_flags = 0; 553 uint32_t flags = 0; 554 vaddr_t va = 0; 555 size_t sz = 0; 556 557 if (exp_pt != param_types) 558 return TEE_ERROR_BAD_PARAMETERS; 559 560 flags = params[0].value.b; 561 562 if ((flags & accept_flags) != flags) 563 return TEE_ERROR_BAD_PARAMETERS; 564 if (flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE) 565 prot |= TEE_MATTR_UW | TEE_MATTR_PW; 566 if (flags & PTA_SYSTEM_MAP_FLAG_EXECUTABLE) 567 prot |= TEE_MATTR_UX; 568 569 va = reg_pair_to_64(params[1].value.a, params[1].value.b), 570 sz = ROUNDUP(params[0].value.a, SMALL_PAGE_SIZE); 571 572 res = vm_get_flags(&utc->uctx, va, sz, &vm_flags); 573 if (res) 574 return res; 575 if (vm_flags & VM_FLAG_PERMANENT) 576 return TEE_ERROR_ACCESS_DENIED; 577 578 /* 579 * If the segment is a mapping of a part of a file (vm_flags & 580 * VM_FLAG_READONLY) it cannot be made writeable as all mapped 581 * files are mapped read-only. 582 */ 583 if ((vm_flags & VM_FLAG_READONLY) && 584 (prot & (TEE_MATTR_UW | TEE_MATTR_PW))) 585 return TEE_ERROR_ACCESS_DENIED; 586 587 return vm_set_prot(&utc->uctx, va, sz, prot); 588 } 589 590 static TEE_Result system_remap(struct tee_ta_session *s, uint32_t param_types, 591 TEE_Param params[TEE_NUM_PARAMS]) 592 { 593 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 594 TEE_PARAM_TYPE_VALUE_INPUT, 595 TEE_PARAM_TYPE_VALUE_INOUT, 596 TEE_PARAM_TYPE_VALUE_INPUT); 597 struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx); 598 TEE_Result res = TEE_SUCCESS; 599 uint32_t num_bytes = 0; 600 uint32_t pad_begin = 0; 601 uint32_t vm_flags = 0; 602 uint32_t pad_end = 0; 603 vaddr_t old_va = 0; 604 vaddr_t new_va = 0; 605 606 if (exp_pt != param_types) 607 return TEE_ERROR_BAD_PARAMETERS; 608 609 num_bytes = params[0].value.a; 610 old_va = reg_pair_to_64(params[1].value.a, params[1].value.b); 611 new_va = reg_pair_to_64(params[2].value.a, params[2].value.b); 612 pad_begin = params[3].value.a; 613 pad_end = params[3].value.b; 614 615 res = vm_get_flags(&utc->uctx, old_va, num_bytes, &vm_flags); 616 if (res) 617 return res; 618 if (vm_flags & VM_FLAG_PERMANENT) 619 return TEE_ERROR_ACCESS_DENIED; 620 621 res = vm_remap(&utc->uctx, &new_va, old_va, num_bytes, pad_begin, 622 pad_end); 623 if (!res) 624 reg_pair_from_64(new_va, ¶ms[2].value.a, 625 ¶ms[2].value.b); 626 627 return res; 628 } 629 630 /* ldelf has the same architecture/register width as the kernel */ 631 #ifdef ARM32 632 static const bool is_arm32 = true; 633 #else 634 static const bool is_arm32; 635 #endif 636 637 static TEE_Result call_ldelf_dlopen(struct user_ta_ctx *utc, TEE_UUID *uuid, 638 uint32_t flags) 639 { 640 uaddr_t usr_stack = utc->ldelf_stack_ptr; 641 TEE_Result res = TEE_ERROR_GENERIC; 642 struct dl_entry_arg *arg = NULL; 643 uint32_t panic_code = 0; 644 uint32_t panicked = 0; 645 646 assert(uuid); 647 648 usr_stack -= ROUNDUP(sizeof(*arg), STACK_ALIGNMENT); 649 arg = (struct dl_entry_arg *)usr_stack; 650 651 res = tee_mmu_check_access_rights(&utc->uctx, 652 TEE_MEMORY_ACCESS_READ | 653 TEE_MEMORY_ACCESS_WRITE | 654 TEE_MEMORY_ACCESS_ANY_OWNER, 655 (uaddr_t)arg, sizeof(*arg)); 656 if (res) { 657 EMSG("ldelf stack is inaccessible!"); 658 return res; 659 } 660 661 memset(arg, 0, sizeof(*arg)); 662 arg->cmd = LDELF_DL_ENTRY_DLOPEN; 663 arg->dlopen.uuid = *uuid; 664 arg->dlopen.flags = flags; 665 666 res = thread_enter_user_mode((vaddr_t)arg, 0, 0, 0, 667 usr_stack, utc->dl_entry_func, 668 is_arm32, &panicked, &panic_code); 669 if (panicked) { 670 EMSG("ldelf dl_entry function panicked"); 671 abort_print_current_ta(); 672 res = TEE_ERROR_TARGET_DEAD; 673 } 674 if (!res) 675 res = arg->ret; 676 677 return res; 678 } 679 680 static TEE_Result call_ldelf_dlsym(struct user_ta_ctx *utc, TEE_UUID *uuid, 681 const char *sym, size_t maxlen, vaddr_t *val) 682 { 683 uaddr_t usr_stack = utc->ldelf_stack_ptr; 684 TEE_Result res = TEE_ERROR_GENERIC; 685 struct dl_entry_arg *arg = NULL; 686 uint32_t panic_code = 0; 687 uint32_t panicked = 0; 688 size_t len = strnlen(sym, maxlen); 689 690 if (len == maxlen) 691 return TEE_ERROR_BAD_PARAMETERS; 692 693 usr_stack -= ROUNDUP(sizeof(*arg) + len + 1, STACK_ALIGNMENT); 694 arg = (struct dl_entry_arg *)usr_stack; 695 696 res = tee_mmu_check_access_rights(&utc->uctx, 697 TEE_MEMORY_ACCESS_READ | 698 TEE_MEMORY_ACCESS_WRITE | 699 TEE_MEMORY_ACCESS_ANY_OWNER, 700 (uaddr_t)arg, sizeof(*arg) + len + 1); 701 if (res) { 702 EMSG("ldelf stack is inaccessible!"); 703 return res; 704 } 705 706 memset(arg, 0, sizeof(*arg)); 707 arg->cmd = LDELF_DL_ENTRY_DLSYM; 708 arg->dlsym.uuid = *uuid; 709 memcpy(arg->dlsym.symbol, sym, len); 710 arg->dlsym.symbol[len] = '\0'; 711 712 res = thread_enter_user_mode((vaddr_t)arg, 0, 0, 0, 713 usr_stack, utc->dl_entry_func, 714 is_arm32, &panicked, &panic_code); 715 if (panicked) { 716 EMSG("ldelf dl_entry function panicked"); 717 abort_print_current_ta(); 718 res = TEE_ERROR_TARGET_DEAD; 719 } 720 if (!res) { 721 res = arg->ret; 722 if (!res) 723 *val = arg->dlsym.val; 724 } 725 726 return res; 727 } 728 729 static TEE_Result system_dlopen(struct tee_ta_session *cs, uint32_t param_types, 730 TEE_Param params[TEE_NUM_PARAMS]) 731 { 732 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 733 TEE_PARAM_TYPE_VALUE_INPUT, 734 TEE_PARAM_TYPE_NONE, 735 TEE_PARAM_TYPE_NONE); 736 TEE_Result res = TEE_ERROR_GENERIC; 737 struct tee_ta_session *s = NULL; 738 struct user_ta_ctx *utc = NULL; 739 TEE_UUID *uuid = NULL; 740 uint32_t flags = 0; 741 742 if (exp_pt != param_types) 743 return TEE_ERROR_BAD_PARAMETERS; 744 745 uuid = params[0].memref.buffer; 746 if (!uuid || params[0].memref.size != sizeof(*uuid)) 747 return TEE_ERROR_BAD_PARAMETERS; 748 749 flags = params[1].value.a; 750 751 utc = to_user_ta_ctx(cs->ctx); 752 753 s = tee_ta_pop_current_session(); 754 res = call_ldelf_dlopen(utc, uuid, flags); 755 tee_ta_push_current_session(s); 756 757 return res; 758 } 759 760 static TEE_Result system_dlsym(struct tee_ta_session *cs, uint32_t param_types, 761 TEE_Param params[TEE_NUM_PARAMS]) 762 { 763 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 764 TEE_PARAM_TYPE_MEMREF_INPUT, 765 TEE_PARAM_TYPE_VALUE_OUTPUT, 766 TEE_PARAM_TYPE_NONE); 767 TEE_Result res = TEE_ERROR_GENERIC; 768 struct tee_ta_session *s = NULL; 769 struct user_ta_ctx *utc = NULL; 770 const char *sym = NULL; 771 TEE_UUID *uuid = NULL; 772 size_t maxlen = 0; 773 vaddr_t va = 0; 774 775 if (exp_pt != param_types) 776 return TEE_ERROR_BAD_PARAMETERS; 777 778 uuid = params[0].memref.buffer; 779 if (uuid && params[0].memref.size != sizeof(*uuid)) 780 return TEE_ERROR_BAD_PARAMETERS; 781 782 sym = params[1].memref.buffer; 783 if (!sym) 784 return TEE_ERROR_BAD_PARAMETERS; 785 maxlen = params[1].memref.size; 786 787 utc = to_user_ta_ctx(cs->ctx); 788 789 s = tee_ta_pop_current_session(); 790 res = call_ldelf_dlsym(utc, uuid, sym, maxlen, &va); 791 tee_ta_push_current_session(s); 792 793 if (!res) 794 reg_pair_from_64(va, ¶ms[2].value.a, ¶ms[2].value.b); 795 796 return res; 797 } 798 799 static TEE_Result system_get_tpm_event_log(uint32_t param_types, 800 TEE_Param params[TEE_NUM_PARAMS]) 801 { 802 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT, 803 TEE_PARAM_TYPE_NONE, 804 TEE_PARAM_TYPE_NONE, 805 TEE_PARAM_TYPE_NONE); 806 size_t size = 0; 807 TEE_Result res = TEE_SUCCESS; 808 809 if (exp_pt != param_types) 810 return TEE_ERROR_BAD_PARAMETERS; 811 812 size = params[0].memref.size; 813 res = tpm_get_event_log(params[0].memref.buffer, &size); 814 params[0].memref.size = size; 815 816 return res; 817 } 818 819 static TEE_Result open_session(uint32_t param_types __unused, 820 TEE_Param params[TEE_NUM_PARAMS] __unused, 821 void **sess_ctx) 822 { 823 struct tee_ta_session *s = NULL; 824 struct system_ctx *ctx = NULL; 825 826 /* Check that we're called from a user TA */ 827 s = tee_ta_get_calling_session(); 828 if (!s) 829 return TEE_ERROR_ACCESS_DENIED; 830 if (!is_user_ta_ctx(s->ctx)) 831 return TEE_ERROR_ACCESS_DENIED; 832 833 ctx = calloc(1, sizeof(*ctx)); 834 if (!ctx) 835 return TEE_ERROR_OUT_OF_MEMORY; 836 837 *sess_ctx = ctx; 838 839 return TEE_SUCCESS; 840 } 841 842 static void close_session(void *sess_ctx) 843 { 844 struct system_ctx *ctx = sess_ctx; 845 846 handle_db_destroy(&ctx->db, ta_bin_close); 847 free(ctx); 848 } 849 850 static TEE_Result invoke_command(void *sess_ctx, uint32_t cmd_id, 851 uint32_t param_types, 852 TEE_Param params[TEE_NUM_PARAMS]) 853 { 854 struct tee_ta_session *s = tee_ta_get_calling_session(); 855 856 switch (cmd_id) { 857 case PTA_SYSTEM_ADD_RNG_ENTROPY: 858 return system_rng_reseed(s, param_types, params); 859 case PTA_SYSTEM_DERIVE_TA_UNIQUE_KEY: 860 return system_derive_ta_unique_key(s, param_types, params); 861 case PTA_SYSTEM_MAP_ZI: 862 return system_map_zi(s, param_types, params); 863 case PTA_SYSTEM_UNMAP: 864 return system_unmap(s, param_types, params); 865 case PTA_SYSTEM_OPEN_TA_BINARY: 866 return system_open_ta_binary(sess_ctx, param_types, params); 867 case PTA_SYSTEM_CLOSE_TA_BINARY: 868 return system_close_ta_binary(sess_ctx, param_types, params); 869 case PTA_SYSTEM_MAP_TA_BINARY: 870 return system_map_ta_binary(sess_ctx, s, param_types, params); 871 case PTA_SYSTEM_COPY_FROM_TA_BINARY: 872 return system_copy_from_ta_binary(sess_ctx, param_types, 873 params); 874 case PTA_SYSTEM_SET_PROT: 875 return system_set_prot(s, param_types, params); 876 case PTA_SYSTEM_REMAP: 877 return system_remap(s, param_types, params); 878 case PTA_SYSTEM_DLOPEN: 879 return system_dlopen(s, param_types, params); 880 case PTA_SYSTEM_DLSYM: 881 return system_dlsym(s, param_types, params); 882 case PTA_SYSTEM_GET_TPM_EVENT_LOG: 883 return system_get_tpm_event_log(param_types, params); 884 default: 885 break; 886 } 887 888 return TEE_ERROR_NOT_IMPLEMENTED; 889 } 890 891 pseudo_ta_register(.uuid = PTA_SYSTEM_UUID, .name = "system.pta", 892 .flags = PTA_DEFAULT_FLAGS | TA_FLAG_CONCURRENT, 893 .open_session_entry_point = open_session, 894 .close_session_entry_point = close_session, 895 .invoke_command_entry_point = invoke_command); 896