1 /* 2 * Copyright (c) 2014, STMicroelectronics International N.V. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 #include <kernel/util.h> 28 #include <kernel/tee_common_otp.h> 29 #include <kernel/tee_common.h> 30 #include <kernel/tee_compat.h> 31 #include <tee_api_types.h> 32 #include <kernel/tee_ta_manager.h> 33 #include <utee_types.h> 34 #include <tee/tee_svc.h> 35 #include <mm/tee_mmu.h> 36 #include <mm/tee_mm.h> 37 #include <kernel/tee_rpc.h> 38 #include <kernel/tee_rpc_types.h> 39 #include <kernel/tee_time.h> 40 41 #include <user_ta_header.h> 42 #include <kernel/tee_core_trace.h> 43 #include <kernel/tee_kta_trace.h> 44 #include <kernel/chip_services.h> 45 #include <tee/tee_hash.h> 46 47 48 void tee_svc_sys_log(const void *buf, size_t len) 49 { 50 char *kbuf; 51 52 if (len == 0) 53 return; 54 55 kbuf = malloc(len); 56 if (kbuf == NULL) 57 return; 58 *kbuf = '\0'; 59 60 /* log as Info/Raw traces */ 61 if (tee_svc_copy_from_user(NULL, kbuf, buf, len) == TEE_SUCCESS) 62 ATAMSG_RAW("%s", kbuf); 63 64 free(kbuf); 65 } 66 67 void tee_svc_sys_panic(uint32_t code) 68 { 69 struct tee_ta_session *sess; 70 71 if (tee_ta_get_current_session(&sess) == TEE_SUCCESS) { 72 EMSG("Set session %p to panicked", (void *)sess); 73 sess->ctx->panicked = 1; 74 sess->ctx->panic_code = code; 75 76 { 77 int *p = 0; 78 79 /* 80 * Force panicking. This memory error will be trapped by 81 * the error exception handler myErrorHandler() 82 */ 83 EMSG("Following 'DTLB exception in bundle'"); 84 EMSG(" is generated with code %d", code); 85 *p = 1; 86 } 87 } else { 88 DMSG("Panic called from unknown TA"); 89 } 90 } 91 92 TEE_Result tee_svc_reserved(void) 93 { 94 return TEE_ERROR_GENERIC; 95 } 96 97 uint32_t tee_svc_sys_dummy(uint32_t *a __unused) 98 { 99 DMSG("tee_svc_sys_dummy: a 0x%x", (unsigned int)a); 100 return 0; 101 } 102 103 uint32_t tee_svc_sys_dummy_7args(uint32_t a1 __unused, uint32_t a2 __unused, 104 uint32_t a3 __unused, uint32_t a4 __unused, 105 uint32_t a5 __unused, uint32_t a6 __unused, 106 uint32_t a7 __unused) 107 { 108 DMSG("tee_svc_sys_dummy_7args: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, %x, %x\n", 109 a1, a2, a3, a4, a5, a6, a7); 110 return 0; 111 } 112 113 uint32_t tee_svc_sys_nocall(void) 114 { 115 DMSG("No syscall"); 116 return 0x1; 117 } 118 119 TEE_Result tee_svc_sys_get_property(uint32_t prop, tee_uaddr_t buf, size_t blen) 120 { 121 static const char api_vers[] = "1.0"; 122 static const char descr[] = "Version N.N"; 123 /* 124 * Value 100 means: 125 * System time based on REE-controlled timers. Can be tampered by the 126 * REE. The implementation must still guarantee that the system time 127 * is monotonous, i.e., successive calls to TEE_GetSystemTime must 128 * return increasing values of the system time. 129 */ 130 static const uint32_t sys_time_prot_lvl = 100; 131 static const uint32_t ta_time_prot_lvl = 100; 132 struct tee_ta_session *sess; 133 TEE_Result res; 134 135 res = tee_ta_get_current_session(&sess); 136 if (res != TEE_SUCCESS) 137 return res; 138 139 switch (prop) { 140 case UTEE_PROP_TEE_API_VERSION: 141 if (blen < sizeof(api_vers)) 142 return TEE_ERROR_SHORT_BUFFER; 143 return tee_svc_copy_to_user(sess, (void *)buf, api_vers, 144 sizeof(api_vers)); 145 146 case UTEE_PROP_TEE_DESCR: 147 if (blen < sizeof(descr)) 148 return TEE_ERROR_SHORT_BUFFER; 149 return tee_svc_copy_to_user(sess, (void *)buf, descr, 150 sizeof(descr)); 151 152 case UTEE_PROP_TEE_DEV_ID: 153 { 154 TEE_UUID uuid; 155 const size_t nslen = 4; 156 uint8_t data[4 + 157 FVR_DIE_ID_NUM_REGS * sizeof(uint32_t)] = { 158 'S', 'T', 'E', 'E' }; 159 160 if (blen < sizeof(uuid)) 161 return TEE_ERROR_SHORT_BUFFER; 162 163 if (tee_otp_get_die_id 164 (data + nslen, sizeof(data) - nslen)) 165 return TEE_ERROR_BAD_STATE; 166 167 res = tee_hash_createdigest( 168 TEE_ALG_SHA256, 169 data, sizeof(data), 170 (uint8_t *)&uuid, sizeof(uuid)); 171 if (res != TEE_SUCCESS) 172 return TEE_ERROR_BAD_STATE; 173 174 /* 175 * Changes the random value into and UUID as specifiec 176 * in RFC 4122. The magic values are from the example 177 * code in the RFC. 178 * 179 * TEE_UUID is defined slightly different from the RFC, 180 * but close enough for our purpose. 181 */ 182 183 uuid.timeHiAndVersion &= 0x0fff; 184 uuid.timeHiAndVersion |= 5 << 12; 185 186 /* uuid.clock_seq_hi_and_reserved in the RFC */ 187 uuid.clockSeqAndNode[0] &= 0x3f; 188 uuid.clockSeqAndNode[0] |= 0x80; 189 190 return tee_svc_copy_to_user(sess, (void *)buf, &uuid, 191 sizeof(TEE_UUID)); 192 } 193 194 case UTEE_PROP_TEE_SYS_TIME_PROT_LEVEL: 195 if (blen < sizeof(sys_time_prot_lvl)) 196 return TEE_ERROR_SHORT_BUFFER; 197 return tee_svc_copy_to_user(sess, (void *)buf, 198 &sys_time_prot_lvl, 199 sizeof(sys_time_prot_lvl)); 200 201 case UTEE_PROP_TEE_TA_TIME_PROT_LEVEL: 202 if (blen < sizeof(ta_time_prot_lvl)) 203 return TEE_ERROR_SHORT_BUFFER; 204 return tee_svc_copy_to_user(sess, (void *)buf, 205 &ta_time_prot_lvl, 206 sizeof(ta_time_prot_lvl)); 207 208 case UTEE_PROP_CLIENT_ID: 209 { 210 if (blen < sizeof(TEE_Identity)) 211 return TEE_ERROR_SHORT_BUFFER; 212 213 return tee_svc_copy_to_user(sess, (void *)buf, 214 &sess->clnt_id, 215 sizeof(TEE_Identity)); 216 } 217 case UTEE_PROP_TA_APP_ID: 218 { 219 if (blen < sizeof(TEE_UUID)) 220 return TEE_ERROR_SHORT_BUFFER; 221 222 return tee_svc_copy_to_user(sess, (void *)buf, 223 &sess->ctx->head->uuid, 224 sizeof(TEE_UUID)); 225 } 226 227 default: 228 break; 229 } 230 return TEE_ERROR_NOT_IMPLEMENTED; 231 } 232 233 /* 234 * TA invokes some TA with parameter. 235 * If some parameters are memory references: 236 * - either the memref is inside TA private RAM: TA is not allowed to expose 237 * its private RAM: use a temporary memory buffer and copy the data. 238 * - or the memref is not in the TA private RAM: 239 * - if the memref was mapped to the TA, TA is allowed to expose it. 240 * - if so, converts memref virtual address into a physical address. 241 */ 242 static TEE_Result tee_svc_copy_param(struct tee_ta_session *sess, 243 struct tee_ta_session *called_sess, 244 uint32_t param_types, 245 TEE_Param callee_params[TEE_NUM_PARAMS], 246 struct tee_ta_param *param, 247 tee_paddr_t tmp_buf_pa[TEE_NUM_PARAMS], 248 tee_mm_entry_t **mm) 249 { 250 size_t n; 251 TEE_Result res; 252 size_t req_mem = 0; 253 size_t s; 254 uint8_t *dst = 0; 255 tee_paddr_t dst_pa, src_pa = 0; 256 bool ta_private_memref[TEE_NUM_PARAMS]; 257 258 /* fill 'param' input struct with caller params description buffer */ 259 param->types = param_types; 260 if (!callee_params) { 261 if (param->types != 0) 262 return TEE_ERROR_BAD_PARAMETERS; 263 memset(param->params, 0, sizeof(param->params)); 264 } else { 265 tee_svc_copy_from_user(sess, param->params, callee_params, 266 sizeof(param->params)); 267 } 268 269 if ((called_sess != NULL) && 270 (called_sess->ctx->static_ta == NULL) && 271 (called_sess->ctx->flags & TA_FLAG_USER_MODE) == 0) { 272 /* 273 * kernel TA, borrow the mapping of the calling 274 * during this call. 275 */ 276 called_sess->calling_sess = sess; 277 return TEE_SUCCESS; 278 } 279 280 for (n = 0; n < TEE_NUM_PARAMS; n++) { 281 282 ta_private_memref[n] = false; 283 284 switch (TEE_PARAM_TYPE_GET(param->types, n)) { 285 case TEE_PARAM_TYPE_MEMREF_INPUT: 286 case TEE_PARAM_TYPE_MEMREF_OUTPUT: 287 case TEE_PARAM_TYPE_MEMREF_INOUT: 288 if (param->params[n].memref.buffer == NULL) { 289 if (param->params[n].memref.size != 0) 290 return TEE_ERROR_BAD_PARAMETERS; 291 break; 292 } 293 /* uTA cannot expose its private memory */ 294 if (tee_mmu_is_vbuf_inside_ta_private(sess->ctx, 295 (uintptr_t)param->params[n].memref.buffer, 296 param->params[n].memref.size)) { 297 298 s = ROUNDUP(param->params[n].memref.size, 299 sizeof(uint32_t)); 300 /* Check overflow */ 301 if (req_mem + s < req_mem) 302 return TEE_ERROR_BAD_PARAMETERS; 303 req_mem += s; 304 ta_private_memref[n] = true; 305 break; 306 } 307 if (!tee_mmu_is_vbuf_outside_ta_private(sess->ctx, 308 (uintptr_t)param->params[n].memref.buffer, 309 param->params[n].memref.size)) 310 return TEE_ERROR_BAD_PARAMETERS; 311 312 if (tee_mmu_user_va2pa(sess->ctx, 313 (void *)param->params[n].memref.buffer, 314 &src_pa) != TEE_SUCCESS) 315 return TEE_ERROR_BAD_PARAMETERS; 316 317 param->param_attr[n] = tee_mmu_user_get_cache_attr( 318 sess->ctx, 319 (void *)param->params[n].memref.buffer); 320 321 param->params[n].memref.buffer = (void *)src_pa; 322 break; 323 324 default: 325 break; 326 } 327 } 328 329 if (req_mem == 0) 330 return TEE_SUCCESS; 331 332 /* Allocate section in secure DDR */ 333 *mm = tee_mm_alloc(&tee_mm_sec_ddr, req_mem); 334 if (*mm == NULL) { 335 DMSG("tee_mm_alloc TEE_ERROR_GENERIC"); 336 return TEE_ERROR_GENERIC; 337 } 338 339 /* Get the virtual address for the section in secure DDR */ 340 res = tee_mmu_kmap(tee_mm_get_smem(*mm), req_mem, &dst); 341 if (res != TEE_SUCCESS) 342 return res; 343 dst_pa = tee_mm_get_smem(*mm); 344 345 for (n = 0; n < 4; n++) { 346 347 if (ta_private_memref[n] == false) 348 continue; 349 350 s = ROUNDUP(param->params[n].memref.size, sizeof(uint32_t)); 351 352 switch (TEE_PARAM_TYPE_GET(param->types, n)) { 353 case TEE_PARAM_TYPE_MEMREF_INPUT: 354 case TEE_PARAM_TYPE_MEMREF_INOUT: 355 if (param->params[n].memref.buffer != NULL) { 356 res = tee_svc_copy_from_user(sess, dst, 357 param->params[n].memref.buffer, 358 param->params[n].memref.size); 359 if (res != TEE_SUCCESS) 360 return res; 361 param->param_attr[n] = 362 tee_mmu_kmap_get_cache_attr(dst); 363 param->params[n].memref.buffer = (void *)dst_pa; 364 tmp_buf_pa[n] = dst_pa; 365 dst += s; 366 dst_pa += s; 367 } 368 break; 369 370 case TEE_PARAM_TYPE_MEMREF_OUTPUT: 371 if (param->params[n].memref.buffer != NULL) { 372 param->param_attr[n] = 373 tee_mmu_kmap_get_cache_attr(dst); 374 param->params[n].memref.buffer = (void *)dst_pa; 375 tmp_buf_pa[n] = dst_pa; 376 dst += s; 377 dst_pa += s; 378 } 379 break; 380 381 default: 382 continue; 383 } 384 } 385 386 tee_mmu_kunmap(dst, req_mem); 387 388 return TEE_SUCCESS; 389 } 390 391 /* 392 * Back from execution of service: update parameters passed from TA: 393 * If some parameters were memory references: 394 * - either the memref was temporary: copy back data and update size 395 * - or it was the original TA memref: update only the size value. 396 */ 397 static TEE_Result tee_svc_update_out_param( 398 struct tee_ta_session *sess, 399 struct tee_ta_session *called_sess, 400 struct tee_ta_param *param, 401 tee_paddr_t tmp_buf_pa[TEE_NUM_PARAMS], 402 TEE_Param callee_params[TEE_NUM_PARAMS]) 403 { 404 size_t n; 405 bool have_private_mem_map = (called_sess == NULL) || 406 (called_sess->ctx->static_ta != NULL) || 407 ((called_sess->ctx->flags & TA_FLAG_USER_MODE) != 0); 408 409 tee_ta_set_current_session(sess); 410 411 for (n = 0; n < TEE_NUM_PARAMS; n++) { 412 switch (TEE_PARAM_TYPE_GET(param->types, n)) { 413 case TEE_PARAM_TYPE_MEMREF_OUTPUT: 414 case TEE_PARAM_TYPE_MEMREF_INOUT: 415 416 /* outside TA private => memref is valid, update size */ 417 if (!tee_mmu_is_vbuf_inside_ta_private(sess->ctx, 418 (uintptr_t)callee_params[n].memref.buffer, 419 param->params[n].memref.size)) { 420 callee_params[n].memref.size = 421 param->params[n].memref.size; 422 break; 423 } 424 425 /* 426 * If we called a kernel TA the parameters are in shared 427 * memory and no copy is needed. 428 */ 429 if (have_private_mem_map && 430 param->params[n].memref.size <= 431 callee_params[n].memref.size) { 432 uint8_t *src = 0; 433 TEE_Result res; 434 435 /* FIXME: TA_RAM is already mapped ! */ 436 res = tee_mmu_kmap(tmp_buf_pa[n], 437 param->params[n].memref.size, &src); 438 if (res != TEE_SUCCESS) 439 return TEE_ERROR_GENERIC; 440 441 res = tee_svc_copy_to_user(sess, 442 callee_params[n].memref. 443 buffer, src, 444 param->params[n]. 445 memref.size); 446 if (res != TEE_SUCCESS) 447 return res; 448 tee_mmu_kunmap(src, 449 param->params[n].memref.size); 450 451 } 452 callee_params[n].memref.size = param->params[n].memref.size; 453 break; 454 455 case TEE_PARAM_TYPE_VALUE_OUTPUT: 456 case TEE_PARAM_TYPE_VALUE_INOUT: 457 callee_params[n].value = param->params[n].value; 458 break; 459 460 default: 461 continue; 462 } 463 } 464 465 return TEE_SUCCESS; 466 } 467 468 /* Called when a TA calls an OpenSession on another TA */ 469 TEE_Result tee_svc_open_ta_session(const TEE_UUID *dest, 470 uint32_t cancel_req_to, uint32_t param_types, 471 TEE_Param params[4], 472 TEE_TASessionHandle *ta_sess, 473 uint32_t *ret_orig) 474 { 475 TEE_Result res; 476 uint32_t ret_o = TEE_ORIGIN_TEE; 477 struct tee_ta_session *s = NULL; 478 struct tee_ta_session *sess; 479 tee_mm_entry_t *mm_param = NULL; 480 481 TEE_UUID *uuid = malloc(sizeof(TEE_UUID)); 482 struct tee_ta_param *param = malloc(sizeof(struct tee_ta_param)); 483 TEE_Identity *clnt_id = malloc(sizeof(TEE_Identity)); 484 tee_paddr_t tmp_buf_pa[TEE_NUM_PARAMS]; 485 486 if (uuid == NULL || param == NULL || clnt_id == NULL) { 487 res = TEE_ERROR_OUT_OF_MEMORY; 488 goto out_free_only; 489 } 490 491 memset(param, 0, sizeof(struct tee_ta_param)); 492 493 res = tee_ta_get_current_session(&sess); 494 if (res != TEE_SUCCESS) 495 goto out_free_only; 496 497 res = tee_svc_copy_from_user(sess, uuid, dest, sizeof(TEE_UUID)); 498 if (res != TEE_SUCCESS) 499 goto function_exit; 500 501 clnt_id->login = TEE_LOGIN_TRUSTED_APP; 502 memcpy(&clnt_id->uuid, &sess->ctx->head->uuid, sizeof(TEE_UUID)); 503 504 res = tee_svc_copy_param(sess, NULL, param_types, params, param, 505 tmp_buf_pa, &mm_param); 506 if (res != TEE_SUCCESS) 507 goto function_exit; 508 509 /* 510 * Find session of a multi session TA or a static TA 511 * In such a case, there is no need to ask the supplicant for the TA 512 * code 513 */ 514 res = tee_ta_open_session(&ret_o, &s, &sess->ctx->open_sessions, uuid, 515 clnt_id, cancel_req_to, param); 516 if (res != TEE_SUCCESS) 517 goto function_exit; 518 519 res = tee_svc_update_out_param(sess, NULL, param, tmp_buf_pa, params); 520 521 function_exit: 522 tee_ta_set_current_session(sess); 523 524 if (mm_param != NULL) { 525 TEE_Result res2; 526 void *va = 0; 527 528 res2 = 529 tee_mmu_kmap_pa2va((void *)tee_mm_get_smem(mm_param), &va); 530 if (res2 == TEE_SUCCESS) 531 tee_mmu_kunmap(va, tee_mm_get_bytes(mm_param)); 532 } 533 tee_mm_free(mm_param); 534 tee_svc_copy_to_user(sess, ta_sess, &s, sizeof(s)); 535 tee_svc_copy_to_user(sess, ret_orig, &ret_o, sizeof(ret_o)); 536 537 out_free_only: 538 free(param); 539 free(uuid); 540 free(clnt_id); 541 return res; 542 } 543 544 TEE_Result tee_svc_close_ta_session(TEE_TASessionHandle ta_sess) 545 { 546 TEE_Result res; 547 struct tee_ta_session *sess; 548 549 res = tee_ta_get_current_session(&sess); 550 if (res != TEE_SUCCESS) 551 return res; 552 553 tee_ta_set_current_session(NULL); 554 555 res = 556 tee_ta_close_session((uint32_t)ta_sess, &sess->ctx->open_sessions); 557 tee_ta_set_current_session(sess); 558 return res; 559 } 560 561 TEE_Result tee_svc_invoke_ta_command(TEE_TASessionHandle ta_sess, 562 uint32_t cancel_req_to, uint32_t cmd_id, 563 uint32_t param_types, TEE_Param params[4], 564 uint32_t *ret_orig) 565 { 566 TEE_Result res; 567 uint32_t ret_o = TEE_ORIGIN_TEE; 568 struct tee_ta_param param = { 0 }; 569 struct tee_ta_session *sess; 570 struct tee_ta_session *called_sess = (struct tee_ta_session *)ta_sess; 571 tee_mm_entry_t *mm_param = NULL; 572 tee_paddr_t tmp_buf_pa[TEE_NUM_PARAMS]; 573 574 res = tee_ta_get_current_session(&sess); 575 if (res != TEE_SUCCESS) 576 return res; 577 578 res = 579 tee_ta_verify_session_pointer(called_sess, 580 &sess->ctx->open_sessions); 581 if (res != TEE_SUCCESS) 582 return res; 583 584 res = tee_svc_copy_param(sess, called_sess, param_types, params, 585 ¶m, tmp_buf_pa, &mm_param); 586 if (res != TEE_SUCCESS) 587 goto function_exit; 588 589 res = 590 tee_ta_invoke_command(&ret_o, called_sess, cancel_req_to, 591 cmd_id, ¶m); 592 if (res != TEE_SUCCESS) 593 goto function_exit; 594 595 res = tee_svc_update_out_param(sess, called_sess, ¶m, tmp_buf_pa, 596 params); 597 if (res != TEE_SUCCESS) 598 goto function_exit; 599 600 function_exit: 601 tee_ta_set_current_session(sess); 602 called_sess->calling_sess = NULL; /* clear eventual borrowed mapping */ 603 604 if (mm_param != NULL) { 605 TEE_Result res2; 606 void *va = 0; 607 608 res2 = 609 tee_mmu_kmap_pa2va((void *)tee_mm_get_smem(mm_param), &va); 610 if (res2 == TEE_SUCCESS) 611 tee_mmu_kunmap(va, tee_mm_get_bytes(mm_param)); 612 } 613 tee_mm_free(mm_param); 614 if (ret_orig) 615 tee_svc_copy_to_user(sess, ret_orig, &ret_o, sizeof(ret_o)); 616 return res; 617 } 618 619 TEE_Result tee_svc_check_access_rights(uint32_t flags, const void *buf, 620 size_t len) 621 { 622 TEE_Result res; 623 struct tee_ta_session *s; 624 625 res = tee_ta_get_current_session(&s); 626 if (res != TEE_SUCCESS) 627 return res; 628 629 return tee_mmu_check_access_rights(s->ctx, flags, (tee_uaddr_t)buf, 630 len); 631 } 632 633 TEE_Result tee_svc_copy_from_user(struct tee_ta_session *sess, void *kaddr, 634 const void *uaddr, size_t len) 635 { 636 TEE_Result res; 637 struct tee_ta_session *s; 638 639 if (sess == NULL) { 640 res = tee_ta_get_current_session(&s); 641 if (res != TEE_SUCCESS) 642 return res; 643 } else { 644 s = sess; 645 tee_ta_set_current_session(s); 646 } 647 res = 648 tee_mmu_check_access_rights(s->ctx, 649 TEE_MEMORY_ACCESS_READ | 650 TEE_MEMORY_ACCESS_ANY_OWNER, 651 (tee_uaddr_t)uaddr, len); 652 if (res != TEE_SUCCESS) 653 return res; 654 655 memcpy(kaddr, uaddr, len); 656 return TEE_SUCCESS; 657 } 658 659 TEE_Result tee_svc_copy_to_user(struct tee_ta_session *sess, void *uaddr, 660 const void *kaddr, size_t len) 661 { 662 TEE_Result res; 663 struct tee_ta_session *s; 664 665 if (sess == NULL) { 666 res = tee_ta_get_current_session(&s); 667 if (res != TEE_SUCCESS) 668 return res; 669 } else { 670 s = sess; 671 tee_ta_set_current_session(s); 672 } 673 674 res = 675 tee_mmu_check_access_rights(s->ctx, 676 TEE_MEMORY_ACCESS_WRITE | 677 TEE_MEMORY_ACCESS_ANY_OWNER, 678 (tee_uaddr_t)uaddr, len); 679 if (res != TEE_SUCCESS) 680 return res; 681 682 memcpy(uaddr, kaddr, len); 683 return TEE_SUCCESS; 684 } 685 686 static bool session_is_cancelled(struct tee_ta_session *s, TEE_Time *curr_time) 687 { 688 TEE_Time current_time; 689 690 if (s->cancel_mask) 691 return false; 692 693 if (s->cancel) 694 return true; 695 696 if (s->cancel_time.seconds == UINT32_MAX) 697 return false; 698 699 if (curr_time != NULL) 700 current_time = *curr_time; 701 else if (tee_time_get_sys_time(¤t_time) != TEE_SUCCESS) 702 return false; 703 704 if (current_time.seconds > s->cancel_time.seconds || 705 (current_time.seconds == s->cancel_time.seconds && 706 current_time.millis >= s->cancel_time.millis)) { 707 return true; 708 } 709 710 return false; 711 } 712 713 TEE_Result tee_svc_get_cancellation_flag(bool *cancel) 714 { 715 TEE_Result res; 716 struct tee_ta_session *s = NULL; 717 bool c; 718 719 res = tee_ta_get_current_session(&s); 720 if (res != TEE_SUCCESS) 721 return res; 722 723 c = session_is_cancelled(s, NULL); 724 725 return tee_svc_copy_to_user(s, cancel, &c, sizeof(c)); 726 } 727 728 TEE_Result tee_svc_unmask_cancellation(bool *old_mask) 729 { 730 TEE_Result res; 731 struct tee_ta_session *s = NULL; 732 bool m; 733 734 res = tee_ta_get_current_session(&s); 735 if (res != TEE_SUCCESS) 736 return res; 737 738 m = s->cancel_mask; 739 s->cancel_mask = false; 740 return tee_svc_copy_to_user(s, old_mask, &m, sizeof(m)); 741 } 742 743 TEE_Result tee_svc_mask_cancellation(bool *old_mask) 744 { 745 TEE_Result res; 746 struct tee_ta_session *s = NULL; 747 bool m; 748 749 res = tee_ta_get_current_session(&s); 750 if (res != TEE_SUCCESS) 751 return res; 752 753 m = s->cancel_mask; 754 s->cancel_mask = true; 755 return tee_svc_copy_to_user(s, old_mask, &m, sizeof(m)); 756 } 757 758 TEE_Result tee_svc_wait(uint32_t timeout) 759 { 760 TEE_Result res = TEE_SUCCESS; 761 uint32_t mytime = 0; 762 struct tee_ta_session *s; 763 TEE_Time base_time; 764 TEE_Time current_time; 765 766 res = tee_ta_get_current_session(&s); 767 if (res != TEE_SUCCESS) 768 return res; 769 770 res = tee_time_get_sys_time(&base_time); 771 if (res != TEE_SUCCESS) 772 return res; 773 774 while (true) { 775 res = tee_time_get_sys_time(¤t_time); 776 if (res != TEE_SUCCESS) 777 return res; 778 779 if (session_is_cancelled(s, ¤t_time)) 780 return TEE_ERROR_CANCEL; 781 782 mytime = (current_time.seconds - base_time.seconds) * 1000 + 783 (int)current_time.millis - (int)base_time.millis; 784 if (mytime >= timeout) 785 return TEE_SUCCESS; 786 787 tee_time_wait(timeout - mytime); 788 } 789 790 return res; 791 } 792 793 TEE_Result tee_svc_get_time(enum utee_time_category cat, TEE_Time *mytime) 794 { 795 TEE_Result res, res2; 796 struct tee_ta_session *s = NULL; 797 TEE_Time t; 798 799 res = tee_ta_get_current_session(&s); 800 if (res != TEE_SUCCESS) 801 return res; 802 803 switch (cat) { 804 case UTEE_TIME_CAT_SYSTEM: 805 res = tee_time_get_sys_time(&t); 806 break; 807 case UTEE_TIME_CAT_TA_PERSISTENT: 808 res = 809 tee_time_get_ta_time((const void *)&s->ctx->head->uuid, &t); 810 break; 811 case UTEE_TIME_CAT_REE: 812 res = tee_time_get_ree_time(&t); 813 break; 814 default: 815 res = TEE_ERROR_BAD_PARAMETERS; 816 break; 817 } 818 819 if (res == TEE_SUCCESS || res == TEE_ERROR_OVERFLOW) { 820 res2 = tee_svc_copy_to_user(s, mytime, &t, sizeof(t)); 821 if (res2 != TEE_SUCCESS) 822 res = res2; 823 } 824 825 return res; 826 } 827 828 TEE_Result tee_svc_set_ta_time(const TEE_Time *mytime) 829 { 830 TEE_Result res; 831 struct tee_ta_session *s = NULL; 832 TEE_Time t; 833 834 res = tee_ta_get_current_session(&s); 835 if (res != TEE_SUCCESS) 836 return res; 837 838 res = tee_svc_copy_from_user(s, &t, mytime, sizeof(t)); 839 if (res != TEE_SUCCESS) 840 return res; 841 842 return tee_time_set_ta_time((const void *)&s->ctx->head->uuid, &t); 843 } 844