1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (C) 2023, STMicroelectronics 4 */ 5 6 #include <assert.h> 7 #include <elf_parser.h> 8 #include <remoteproc_pta.h> 9 #include <string.h> 10 #include <sys/queue.h> 11 #include <ta_remoteproc.h> 12 #include <tee_internal_api.h> 13 #include <tee_internal_api_extensions.h> 14 #include <types_ext.h> 15 #include <utee_defines.h> 16 17 /* 18 * The remoteproc Trusted Application is in charge of authenticating and loading 19 * images signed by the scripts/sign_rproc_fw.py. The TA is also in charge of 20 * starting and stopping the remote processor. 21 * The structure of the signed image is: 22 * 23 * -----+-------------+ 24 * / | Magic | 32-bit word, magic value equal to 25 * / +-------------+ 0x3543A468 26 * / +-------------+ 27 * / | version | 32-bit word, version of the format 28 * / +-------------+ 29 * +-----------+ +-------------+ 30 * | Header | | TLV size | 32-bit word, size of the TLV 31 * +-----------+ +-------------+ (aligned on 64-bit), in bytes. 32 * \ +-------------+ 33 * \ | sign size | 32-bit word, size of the signature 34 * \ +-------------+ (aligned on 64-bit), in bytes. 35 * \ +-------------+ 36 * \ | images size | 32-bit word, size of the images to 37 * -----+-------------+ load (aligned on 64-bit), in bytes. 38 * 39 * +-------------+ Information used to authenticate the 40 * | TLV | images and boot the remote processor, 41 * | | stored in Type-Length-Value format. 42 * +-------------+ 'Type' and 'Length' are 32-bit words. 43 * 44 * +-------------+ 45 * | Signature | Signature of the header and the TLV. 46 * +-------------+ 47 * 48 * +-------------+ 49 * | Firmware | 50 * | image 1 | 51 * +-------------+ 52 * ... 53 * +-------------+ 54 * | Firmware | 55 * | image n | 56 * +-------------+ 57 */ 58 59 /* Firmware state */ 60 enum remoteproc_state { 61 REMOTEPROC_OFF = 0, 62 REMOTEPROC_LOADED, 63 REMOTEPROC_STARTED, 64 }; 65 66 #define RPROC_HDR_MAGIC 0x3543A468 67 #define HEADER_VERSION 1 68 69 /* Supported signature algorithm */ 70 enum remoteproc_sign_type { 71 RPROC_RSASSA_PKCS1_v1_5_SHA256 = 1, 72 RPROC_ECDSA_SHA256 = 2, 73 }; 74 75 enum remoteproc_img_type { 76 REMOTEPROC_ELF_TYPE = 1, 77 REMOTEPROC_INVALID_TYPE = 0xFF 78 }; 79 80 /* remoteproc_tlv structure offsets */ 81 #define RPROC_TLV_LENGTH_OF U(0x04) 82 #define RPROC_TLV_VALUE_OF U(0x08) 83 84 /* TLV types */ 85 #define RPROC_TLV_SIGNTYPE U(0x00000001) 86 #define RPROC_TLV_HASHTYPE U(0x00000002) 87 #define RPROC_TLV_NUM_IMG U(0x00000003) 88 #define RPROC_TLV_IMGTYPE U(0x00000004) 89 #define RPROC_TLV_IMGSIZE U(0x00000005) 90 #define RPROC_TLV_HASHTABLE U(0x00000010) 91 #define RPROC_TLV_PKEYINFO U(0x00000011) 92 93 #define RPROC_PLAT_TLV_TYPE_MIN U(0x00010000) 94 #define RPROC_PLAT_TLV_TYPE_MAX U(0x00020000) 95 96 #define RPROC_TLV_SIGNTYPE_LGTH U(1) 97 98 #define ROUNDUP_64(x) ROUNDUP((x), sizeof(uint64_t)) 99 100 /* 101 * struct remoteproc_tlv - Type-Length-Value structure 102 * @type: type of data 103 * @length: size of the data. 104 * @value: pointer to the data. 105 */ 106 struct remoteproc_tlv { 107 uint32_t type; 108 uint32_t length; 109 uint8_t value[]; 110 }; 111 112 /* 113 * struct remoteproc_segment - program header with hash structure 114 * @phdr: program header 115 * @hash: hash associated to the program segment. 116 */ 117 struct remoteproc_segment { 118 Elf32_Phdr phdr; 119 uint8_t hash[TEE_SHA256_HASH_SIZE]; 120 }; 121 122 /* 123 * struct remoteproc_fw_hdr - firmware header 124 * @magic: Magic number, must be equal to RPROC_HDR_MAGIC 125 * @version: Version of the header (must be 1) 126 * @tlv_len: Generic meta data chunk (TLV format) 127 * @sign_len: Signature chunk byte length 128 * @img_len: Firmware image chunk byte length 129 */ 130 struct remoteproc_fw_hdr { 131 uint32_t magic; 132 uint32_t version; 133 uint32_t tlv_len; 134 uint32_t sign_len; 135 uint32_t img_len; 136 }; 137 138 #define FW_TLV_PTR(img, hdr) ((img) + sizeof(*(hdr))) 139 #define FW_SIGN_PTR(img, hdr) ({ \ 140 struct remoteproc_fw_hdr *__hdr = (hdr); \ 141 \ 142 FW_TLV_PTR((img), __hdr) + ROUNDUP_64(__hdr->tlv_len); \ 143 }) 144 #define FW_IMG_PTR(img, hdr) ({ \ 145 struct remoteproc_fw_hdr *___hdr = (hdr); \ 146 \ 147 FW_SIGN_PTR((img), ___hdr) + ROUNDUP_64(___hdr->sign_len); \ 148 }) 149 150 /* 151 * struct remoteproc_sig_algo - signature algorithm information 152 * @sign_type: Header signature type 153 * @id: Signature algorithm identifier TEE_ALG_* 154 * @hash_len: Signature hash length 155 */ 156 struct remoteproc_sig_algo { 157 enum remoteproc_sign_type sign_type; 158 uint32_t id; 159 size_t hash_len; 160 }; 161 162 /* 163 * struct remoteproc_context - firmware context 164 * @rproc_id: Unique Id of the processor 165 * @sec_cpy: Location of a secure copy of the header, TLVs and signature 166 * @tlvs: Location of a secure copy of the firmware TLVs 167 * @tlvs_sz: Byte size of the firmware TLVs blob. 168 * @fw_img: Firmware image 169 * @fw_img_sz: Byte size of the firmware image 170 * @hash_table: Location of a copy of the segment's hash table 171 * @nb_segment: number of segment to load 172 * @rsc_pa: Physical address of the firmware resource table 173 * @rsc_size: Byte size of the firmware resource table 174 * @state: Remote-processor state 175 * @hw_fmt: Image format capabilities of the remoteproc PTA 176 * @hw_img_prot: Image protection capabilities of the remoteproc PTA 177 * @link: Linked list element 178 */ 179 struct remoteproc_context { 180 uint32_t rproc_id; 181 uint8_t *sec_cpy; 182 uint8_t *tlvs; 183 size_t tlvs_sz; 184 uint8_t *fw_img; 185 size_t fw_img_sz; 186 struct remoteproc_segment *hash_table; 187 uint32_t nb_segment; 188 paddr_t rsc_pa; 189 size_t rsc_size; 190 enum remoteproc_state state; 191 uint32_t hw_fmt; 192 uint32_t hw_img_prot; 193 TAILQ_ENTRY(remoteproc_context) link; 194 }; 195 196 TAILQ_HEAD(remoteproc_firmware_head, remoteproc_context); 197 198 static struct remoteproc_firmware_head firmware_head = 199 TAILQ_HEAD_INITIALIZER(firmware_head); 200 201 static const struct remoteproc_sig_algo rproc_ta_sign_algo[] = { 202 { 203 .sign_type = RPROC_RSASSA_PKCS1_v1_5_SHA256, 204 .id = TEE_ALG_RSASSA_PKCS1_V1_5_SHA256, 205 .hash_len = TEE_SHA256_HASH_SIZE, 206 }, 207 { 208 .sign_type = RPROC_ECDSA_SHA256, 209 .id = TEE_ALG_ECDSA_P256, 210 .hash_len = TEE_SHA256_HASH_SIZE, 211 }, 212 }; 213 214 static size_t session_refcount; 215 static TEE_TASessionHandle pta_session; 216 217 static void remoteproc_header_dump(struct remoteproc_fw_hdr __maybe_unused *hdr) 218 { 219 DMSG("magic :\t%#"PRIx32, hdr->magic); 220 DMSG("version :\t%#"PRIx32, hdr->version); 221 DMSG("tlv_len :\t%#"PRIx32, hdr->tlv_len); 222 DMSG("sign_len :\t%#"PRIx32, hdr->sign_len); 223 DMSG("img_len :\t%#"PRIx32, hdr->img_len); 224 } 225 226 static TEE_Result remoteproc_get_tlv(void *tlv_chunk, size_t tlv_size, 227 uint16_t type, uint8_t **value, 228 size_t *length) 229 { 230 uint8_t *p_tlv = (uint8_t *)tlv_chunk; 231 uint8_t *p_end_tlv = p_tlv + tlv_size; 232 uint32_t tlv_type = 0; 233 uint32_t tlv_length = 0; 234 uint32_t tlv_v = 0; 235 uintptr_t tmp_p_tlv = 0; 236 237 *value = NULL; 238 *length = 0; 239 240 /* Parse the TLV area */ 241 while (p_tlv + RPROC_TLV_VALUE_OF <= p_end_tlv) { 242 memcpy(&tlv_v, p_tlv, sizeof(tlv_v)); 243 tlv_type = TEE_U32_FROM_LITTLE_ENDIAN(tlv_v); 244 memcpy(&tlv_v, p_tlv + RPROC_TLV_LENGTH_OF, sizeof(tlv_v)); 245 p_tlv += RPROC_TLV_VALUE_OF; 246 tlv_length = TEE_U32_FROM_LITTLE_ENDIAN(tlv_v); 247 if (ADD_OVERFLOW((uintptr_t)p_tlv, tlv_length, &tmp_p_tlv)) 248 break; 249 if (tmp_p_tlv <= (uintptr_t)p_end_tlv && tlv_type == type) { 250 /* The specified TLV has been found */ 251 DMSG("TLV type %#"PRIx32" found, size %#"PRIx32, 252 type, tlv_length); 253 *value = p_tlv; 254 *length = tlv_length; 255 if (tlv_length) 256 return TEE_SUCCESS; 257 else 258 return TEE_ERROR_NO_DATA; 259 } 260 p_tlv += ROUNDUP_64(tlv_length); 261 } 262 263 return TEE_ERROR_NO_DATA; 264 } 265 266 static struct remoteproc_context *remoteproc_find_firmware(uint32_t rproc_id) 267 { 268 struct remoteproc_context *ctx = NULL; 269 270 TAILQ_FOREACH(ctx, &firmware_head, link) 271 if (ctx->rproc_id == rproc_id) 272 return ctx; 273 274 return NULL; 275 } 276 277 static struct remoteproc_context *remoteproc_add_firmware(uint32_t rproc_id) 278 { 279 struct remoteproc_context *ctx = NULL; 280 281 ctx = TEE_Malloc(sizeof(*ctx), TEE_MALLOC_FILL_ZERO); 282 if (!ctx) 283 return NULL; 284 285 ctx->rproc_id = rproc_id; 286 287 TAILQ_INSERT_TAIL(&firmware_head, ctx, link); 288 289 return ctx; 290 } 291 292 static const struct remoteproc_sig_algo *remoteproc_get_algo(uint32_t sign_type) 293 { 294 unsigned int i = 0; 295 296 for (i = 0; i < ARRAY_SIZE(rproc_ta_sign_algo); i++) 297 if (sign_type == rproc_ta_sign_algo[i].sign_type) 298 return &rproc_ta_sign_algo[i]; 299 300 return NULL; 301 } 302 303 static TEE_Result remoteproc_pta_verify(struct remoteproc_context *ctx, 304 const struct remoteproc_sig_algo *algo, 305 uint8_t *hash, uint32_t hash_len) 306 { 307 TEE_Result res = TEE_ERROR_GENERIC; 308 struct remoteproc_fw_hdr *hdr = (void *)ctx->sec_cpy; 309 struct rproc_pta_key_info *keyinfo = NULL; 310 uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 311 TEE_PARAM_TYPE_MEMREF_INPUT, 312 TEE_PARAM_TYPE_MEMREF_INPUT, 313 TEE_PARAM_TYPE_MEMREF_INPUT); 314 TEE_Param params[TEE_NUM_PARAMS] = { }; 315 size_t length = 0; 316 uint8_t *tlv_keyinfo = NULL; 317 uint8_t *sign = NULL; 318 319 res = remoteproc_get_tlv(ctx->tlvs, hdr->tlv_len, 320 RPROC_TLV_PKEYINFO, &tlv_keyinfo, 321 &length); 322 if (res != TEE_SUCCESS && res != TEE_ERROR_NO_DATA) 323 return res; 324 325 keyinfo = TEE_Malloc(sizeof(*keyinfo) + length, TEE_MALLOC_FILL_ZERO); 326 if (!keyinfo) 327 return TEE_ERROR_OUT_OF_MEMORY; 328 329 keyinfo->algo = algo->id; 330 keyinfo->info_size = length; 331 memcpy(keyinfo->info, tlv_keyinfo, length); 332 333 sign = FW_SIGN_PTR(ctx->sec_cpy, hdr); 334 335 params[0].value.a = ctx->rproc_id; 336 params[1].memref.buffer = keyinfo; 337 params[1].memref.size = rproc_pta_keyinfo_size(keyinfo); 338 params[2].memref.buffer = hash; 339 params[2].memref.size = hash_len; 340 params[3].memref.buffer = sign; 341 params[3].memref.size = hdr->sign_len; 342 343 res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, 344 PTA_RPROC_VERIFY_DIGEST, 345 param_types, params, NULL); 346 if (res != TEE_SUCCESS) 347 EMSG("Failed to verify signature, res = %#"PRIx32, res); 348 349 TEE_Free(keyinfo); 350 351 return res; 352 } 353 354 static TEE_Result 355 remoteproc_save_fw_header_and_tlvs(struct remoteproc_context *ctx, 356 void *fw_orig, uint32_t fw_orig_size) 357 { 358 struct remoteproc_fw_hdr *hdr = fw_orig; 359 uint32_t length = 0; 360 361 if (!IS_ALIGNED_WITH_TYPE(fw_orig, struct remoteproc_fw_hdr)) 362 return TEE_ERROR_BAD_PARAMETERS; 363 364 if (ADD_OVERFLOW(sizeof(*hdr), ROUNDUP_64(hdr->tlv_len), &length) || 365 ADD_OVERFLOW(length, ROUNDUP_64(hdr->sign_len), &length)) 366 return TEE_ERROR_BAD_PARAMETERS; 367 368 if (fw_orig_size <= length || !hdr->sign_len || !hdr->tlv_len) 369 return TEE_ERROR_BAD_PARAMETERS; 370 371 remoteproc_header_dump(hdr); 372 373 /* Copy the header, the TLVs and the signature in secure memory */ 374 ctx->sec_cpy = TEE_Malloc(length, TEE_MALLOC_FILL_ZERO); 375 if (!ctx->sec_cpy) 376 return TEE_ERROR_OUT_OF_MEMORY; 377 378 memcpy(ctx->sec_cpy, fw_orig, length); 379 380 return TEE_SUCCESS; 381 } 382 383 static TEE_Result remoteproc_verify_signature(struct remoteproc_context *ctx) 384 { 385 TEE_OperationHandle op = TEE_HANDLE_NULL; 386 struct remoteproc_fw_hdr *hdr = (void *)ctx->sec_cpy; 387 const struct remoteproc_sig_algo *algo = NULL; 388 TEE_Result res = TEE_ERROR_GENERIC; 389 uint8_t *tlv_sign_algo = NULL; 390 size_t length = 0; 391 uint8_t *hash = NULL; 392 size_t hash_len = 0; 393 394 /* Get the algo type from TLV data */ 395 res = remoteproc_get_tlv(ctx->tlvs, hdr->tlv_len, RPROC_TLV_SIGNTYPE, 396 &tlv_sign_algo, &length); 397 398 if (res != TEE_SUCCESS || length != RPROC_TLV_SIGNTYPE_LGTH) 399 return TEE_ERROR_BAD_PARAMETERS; 400 401 algo = remoteproc_get_algo(*tlv_sign_algo); 402 if (!algo) { 403 EMSG("Unsupported signature type %"PRId8, *tlv_sign_algo); 404 return TEE_ERROR_NOT_SUPPORTED; 405 } 406 407 /* Compute the header and TLVs hashes */ 408 hash_len = algo->hash_len; 409 hash = TEE_Malloc(hash_len, TEE_MALLOC_FILL_ZERO); 410 if (!hash) 411 return TEE_ERROR_OUT_OF_MEMORY; 412 413 res = TEE_AllocateOperation(&op, TEE_ALG_SHA256, TEE_MODE_DIGEST, 0); 414 if (res != TEE_SUCCESS) 415 goto free_hash; 416 417 TEE_DigestUpdate(op, hdr, sizeof(*hdr)); 418 res = TEE_DigestDoFinal(op, ctx->tlvs, ROUNDUP_64(hdr->tlv_len), 419 hash, &hash_len); 420 421 if (res != TEE_SUCCESS) 422 goto out; 423 424 /* 425 * This implementation could be enhanced by providing alternative to 426 * verify the signature in the TA. This could be done for instance by 427 * getting the key object from secure storage. 428 */ 429 430 /* By default ask the remoteproc PTA to verify the signature. */ 431 res = remoteproc_pta_verify(ctx, algo, hash, hash_len); 432 433 out: 434 TEE_FreeOperation(op); 435 free_hash: 436 TEE_Free(hash); 437 438 return res; 439 } 440 441 static TEE_Result remoteproc_verify_header(struct remoteproc_context *ctx, 442 uint32_t fw_orig_size) 443 { 444 struct remoteproc_fw_hdr *hdr = (void *)ctx->sec_cpy; 445 uint32_t size = 0; 446 447 if (hdr->magic != RPROC_HDR_MAGIC) 448 return TEE_ERROR_BAD_PARAMETERS; 449 450 if (hdr->version != HEADER_VERSION) 451 return TEE_ERROR_BAD_PARAMETERS; 452 453 /* 454 * The offsets are aligned to 64 bits format. While the length of each 455 * chunks are the effective length, excluding the alignment padding 456 * bytes. 457 */ 458 if (ADD_OVERFLOW(sizeof(*hdr), ROUNDUP_64(hdr->sign_len), &size) || 459 ADD_OVERFLOW(size, ROUNDUP_64(hdr->img_len), &size) || 460 ADD_OVERFLOW(size, ROUNDUP_64(hdr->tlv_len), &size) || 461 fw_orig_size != size) 462 return TEE_ERROR_BAD_PARAMETERS; 463 464 return TEE_SUCCESS; 465 } 466 467 static TEE_Result get_rproc_pta_capabilities(struct remoteproc_context *ctx) 468 { 469 uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 470 TEE_PARAM_TYPE_VALUE_OUTPUT, 471 TEE_PARAM_TYPE_VALUE_OUTPUT, 472 TEE_PARAM_TYPE_NONE); 473 TEE_Param params[TEE_NUM_PARAMS] = { }; 474 TEE_Result res = TEE_ERROR_GENERIC; 475 476 params[0].value.a = ctx->rproc_id; 477 478 res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, 479 PTA_RPROC_HW_CAPABILITIES, 480 param_types, params, NULL); 481 if (res) 482 return res; 483 484 ctx->hw_fmt = params[1].value.a; 485 ctx->hw_img_prot = params[2].value.a; 486 487 return TEE_SUCCESS; 488 } 489 490 static TEE_Result remoteproc_verify_firmware(struct remoteproc_context *ctx, 491 uint8_t *fw_orig, 492 uint32_t fw_orig_size) 493 { 494 struct remoteproc_fw_hdr *hdr = NULL; 495 TEE_Result res = TEE_ERROR_GENERIC; 496 497 res = get_rproc_pta_capabilities(ctx); 498 if (res) 499 return res; 500 501 /* Secure the firmware image depending on strategy */ 502 if (!(ctx->hw_img_prot & PTA_RPROC_HWCAP_PROT_HASH_TABLE) || 503 ctx->hw_fmt != PTA_RPROC_HWCAP_FMT_ELF) { 504 /* 505 * Only hash table for ELF format support implemented 506 * in a first step. 507 */ 508 return TEE_ERROR_NOT_IMPLEMENTED; 509 } 510 511 res = remoteproc_save_fw_header_and_tlvs(ctx, fw_orig, fw_orig_size); 512 if (res) 513 return res; 514 515 res = remoteproc_verify_header(ctx, fw_orig_size); 516 if (res) 517 goto free_sec_cpy; 518 519 hdr = (void *)ctx->sec_cpy; 520 ctx->tlvs_sz = hdr->tlv_len; 521 ctx->tlvs = FW_TLV_PTR(ctx->sec_cpy, hdr); 522 523 res = remoteproc_verify_signature(ctx); 524 if (res) 525 goto free_sec_cpy; 526 527 /* Store location of the loadable binary in non-secure memory */ 528 ctx->fw_img_sz = hdr->img_len; 529 ctx->fw_img = FW_IMG_PTR(fw_orig, hdr); 530 531 DMSG("Firmware images addr: %p size: %zu", ctx->fw_img, 532 ctx->fw_img_sz); 533 534 return TEE_SUCCESS; 535 536 free_sec_cpy: 537 TEE_Free(ctx->sec_cpy); 538 ctx->sec_cpy = NULL; 539 540 return res; 541 } 542 543 static paddr_t remoteproc_da_to_pa(uint32_t da, size_t size, 544 struct remoteproc_context *ctx) 545 { 546 uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 547 TEE_PARAM_TYPE_VALUE_INPUT, 548 TEE_PARAM_TYPE_VALUE_INPUT, 549 TEE_PARAM_TYPE_VALUE_OUTPUT); 550 TEE_Param params[TEE_NUM_PARAMS] = { }; 551 TEE_Result res = TEE_ERROR_GENERIC; 552 paddr_t pa = 0; 553 554 /* 555 * The ELF file contains remote processor device addresses, that refer 556 * to the remote processor memory space. 557 * A translation is needed to get the corresponding physical address. 558 */ 559 560 params[0].value.a = ctx->rproc_id; 561 params[1].value.a = da; 562 params[2].value.a = size; 563 564 res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, 565 PTA_RPROC_FIRMWARE_DA_TO_PA, 566 param_types, params, NULL); 567 if (res != TEE_SUCCESS) { 568 EMSG("Failed to translate device address %#"PRIx32, da); 569 return 0; 570 } 571 572 pa = (paddr_t)reg_pair_to_64(params[3].value.b, params[3].value.a); 573 574 /* Assert that the pa address is not 0 */ 575 assert(pa); 576 577 return pa; 578 } 579 580 static TEE_Result remoteproc_parse_rsc_table(struct remoteproc_context *ctx, 581 uint8_t *fw_img, size_t fw_img_sz, 582 paddr_t *rsc_pa, 583 size_t *rsc_size) 584 { 585 uint32_t da = 0; 586 TEE_Result res = TEE_ERROR_GENERIC; 587 Elf32_Word size = 0; 588 589 res = e32_parser_find_rsc_table(fw_img, fw_img_sz, &da, &size); 590 if (res) 591 return res; 592 593 DMSG("Resource table device address %#"PRIx32" size %#"PRIx32, 594 da, size); 595 596 *rsc_pa = remoteproc_da_to_pa(da, size, ctx); 597 if (!*rsc_pa) 598 return TEE_ERROR_ACCESS_DENIED; 599 600 *rsc_size = size; 601 602 return TEE_SUCCESS; 603 } 604 605 static TEE_Result get_hash_table(struct remoteproc_context *ctx) 606 { 607 TEE_Result res = TEE_ERROR_GENERIC; 608 uint8_t *tlv_hash = NULL; 609 struct remoteproc_segment *hash_table = NULL; 610 size_t length = 0; 611 612 /* Get the segment's hash table from TLV data */ 613 res = remoteproc_get_tlv(ctx->tlvs, ctx->tlvs_sz, RPROC_TLV_HASHTABLE, 614 &tlv_hash, &length); 615 if (res) 616 return res; 617 618 if (length % sizeof(struct remoteproc_segment)) 619 return TEE_ERROR_BAD_PARAMETERS; 620 621 /* We can not ensure that tlv_hash is memory aligned so make a copy */ 622 hash_table = TEE_Malloc(length, TEE_MALLOC_FILL_ZERO); 623 if (!hash_table) 624 return TEE_ERROR_OUT_OF_MEMORY; 625 626 memcpy(hash_table, tlv_hash, length); 627 628 ctx->hash_table = hash_table; 629 ctx->nb_segment = length / sizeof(struct remoteproc_segment); 630 631 return TEE_SUCCESS; 632 } 633 634 static TEE_Result get_tlv_images_type(struct remoteproc_context *ctx, 635 uint8_t num_img, uint8_t idx, 636 uint8_t *img_type) 637 { 638 TEE_Result res = TEE_ERROR_GENERIC; 639 uint8_t *tlv_value = NULL; 640 size_t length = 0; 641 642 /* Get the type of the image to load, from TLV data */ 643 res = remoteproc_get_tlv(ctx->tlvs, ctx->tlvs_sz, RPROC_TLV_IMGTYPE, 644 &tlv_value, &length); 645 if (res) 646 return res; 647 648 if (length != (sizeof(*img_type) * num_img)) 649 return TEE_ERROR_BAD_PARAMETERS; 650 651 *img_type = tlv_value[idx]; 652 653 return TEE_SUCCESS; 654 } 655 656 static TEE_Result get_tlv_images_size(struct remoteproc_context *ctx, 657 uint8_t num_img, uint8_t idx, 658 uint32_t *img_size) 659 { 660 TEE_Result res = TEE_ERROR_GENERIC; 661 uint8_t *tlv_value = NULL; 662 uint32_t tlv_v = 0; 663 size_t length = 0; 664 665 /* Get the size of the image to load, from TLV data */ 666 res = remoteproc_get_tlv(ctx->tlvs, ctx->tlvs_sz, RPROC_TLV_IMGSIZE, 667 &tlv_value, &length); 668 if (res) 669 return res; 670 671 if (length != (sizeof(*img_size) * num_img)) 672 return TEE_ERROR_BAD_PARAMETERS; 673 674 memcpy(&tlv_v, &tlv_value[sizeof(*img_size) * idx], sizeof(tlv_v)); 675 *img_size = TEE_U32_FROM_LITTLE_ENDIAN(tlv_v); 676 677 return TEE_SUCCESS; 678 } 679 680 static TEE_Result get_segment_hash(struct remoteproc_context *ctx, uint8_t *src, 681 uint32_t size, uint32_t da, 682 uint32_t mem_size, uint8_t **hash) 683 { 684 struct remoteproc_segment *peh = NULL; 685 unsigned int i = 0; 686 unsigned int nb_entry = ctx->nb_segment; 687 688 peh = (void *)(ctx->hash_table); 689 690 for (i = 0; i < nb_entry; peh++, i++) { 691 if (peh->phdr.p_paddr != da) 692 continue; 693 694 /* 695 * Segment metadata are read from a non-secure memory. 696 * Validate them using hash table data stored in secure memory. 697 */ 698 if (peh->phdr.p_type != PT_LOAD) 699 return TEE_ERROR_BAD_PARAMETERS; 700 701 if (peh->phdr.p_filesz != size || peh->phdr.p_memsz != mem_size) 702 return TEE_ERROR_BAD_PARAMETERS; 703 704 if (src < ctx->fw_img || 705 src > (ctx->fw_img + ctx->fw_img_sz) || 706 (src + peh->phdr.p_filesz) > (ctx->fw_img + ctx->fw_img_sz)) 707 return TEE_ERROR_BAD_PARAMETERS; 708 709 *hash = peh->hash; 710 711 return TEE_SUCCESS; 712 } 713 714 return TEE_ERROR_NO_DATA; 715 } 716 717 static TEE_Result remoteproc_load_segment(uint8_t *src, uint32_t size, 718 uint32_t da, uint32_t mem_size, 719 void *priv) 720 { 721 struct remoteproc_context *ctx = priv; 722 uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 723 TEE_PARAM_TYPE_MEMREF_INPUT, 724 TEE_PARAM_TYPE_VALUE_INPUT, 725 TEE_PARAM_TYPE_MEMREF_INPUT); 726 TEE_Param params[TEE_NUM_PARAMS] = { }; 727 TEE_Result res = TEE_ERROR_GENERIC; 728 uint8_t *hash = NULL; 729 730 /* 731 * Invoke platform remoteproc PTA to load the segment in remote 732 * processor memory which is not mapped in the TA space. 733 */ 734 735 DMSG("Load segment %#"PRIx32" size %"PRIu32" (%"PRIu32")", da, size, 736 mem_size); 737 738 res = get_segment_hash(ctx, src, size, da, mem_size, &hash); 739 if (res) 740 return res; 741 742 params[0].value.a = ctx->rproc_id; 743 params[1].memref.buffer = src; 744 params[1].memref.size = size; 745 params[2].value.a = da; 746 params[3].memref.buffer = hash; 747 params[3].memref.size = TEE_SHA256_HASH_SIZE; 748 749 if (size) { 750 res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, 751 PTA_RPROC_LOAD_SEGMENT_SHA256, 752 param_types, params, NULL); 753 if (res != TEE_SUCCESS) { 754 EMSG("Fails to load segment, res = 0x%#"PRIx32, res); 755 return res; 756 } 757 } 758 759 /* Fill the rest of the memory with 0 */ 760 if (size < mem_size) { 761 param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 762 TEE_PARAM_TYPE_VALUE_INPUT, 763 TEE_PARAM_TYPE_VALUE_INPUT, 764 TEE_PARAM_TYPE_VALUE_INPUT); 765 params[1].value.a = da + size; 766 params[2].value.a = mem_size - size; 767 params[3].value.a = 0; 768 769 res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, 770 PTA_RPROC_SET_MEMORY, 771 param_types, params, NULL); 772 if (res != TEE_SUCCESS) 773 EMSG("Fails to clear segment, res = %#"PRIx32, res); 774 } 775 776 return res; 777 } 778 779 static TEE_Result remoteproc_load_elf(struct remoteproc_context *ctx) 780 { 781 TEE_Result res = TEE_ERROR_GENERIC; 782 unsigned int num_img = 0; 783 unsigned int i = 0; 784 uint8_t img_type = REMOTEPROC_INVALID_TYPE; 785 uint32_t img_size = 0; 786 uint8_t *tlv = NULL; 787 int32_t offset = 0; 788 size_t length = 0; 789 paddr_t rsc_pa = 0; 790 size_t rsc_size = 0; 791 792 res = e32_parse_ehdr(ctx->fw_img, ctx->fw_img_sz); 793 if (res) { 794 EMSG("Failed to parse firmware, res = %#"PRIx32, res); 795 return res; 796 } 797 798 res = get_hash_table(ctx); 799 if (res) 800 return res; 801 802 /* Get the number of firmware images to load */ 803 res = remoteproc_get_tlv(ctx->tlvs, ctx->tlvs_sz, RPROC_TLV_NUM_IMG, 804 &tlv, &length); 805 if (res) 806 goto out; 807 if (length != sizeof(uint8_t)) { 808 res = TEE_ERROR_BAD_FORMAT; 809 goto out; 810 } 811 812 num_img = *tlv; 813 if (!num_img) { 814 res = TEE_ERROR_NO_DATA; 815 goto out; 816 } 817 818 /* 819 * Initialize resource table with zero. These values will be returned if 820 * no optional resource table is found in images. 821 */ 822 ctx->rsc_pa = 0; 823 ctx->rsc_size = 0; 824 825 for (i = 0; i < num_img; i++) { 826 res = get_tlv_images_type(ctx, num_img, i, &img_type); 827 if (res) 828 goto out; 829 if (img_type != REMOTEPROC_ELF_TYPE) { 830 res = TEE_ERROR_BAD_FORMAT; 831 goto out; 832 } 833 834 res = get_tlv_images_size(ctx, num_img, i, &img_size); 835 if (res) 836 goto out; 837 838 res = e32_parser_load_elf_image(ctx->fw_img + offset, img_size, 839 remoteproc_load_segment, ctx); 840 if (res) 841 goto out; 842 843 /* Take opportunity to get the resource table address */ 844 res = remoteproc_parse_rsc_table(ctx, ctx->fw_img + offset, 845 img_size, &rsc_pa, &rsc_size); 846 if (res != TEE_SUCCESS && res != TEE_ERROR_NO_DATA) 847 goto out; 848 849 if (res == TEE_SUCCESS) { 850 /* 851 * Only one resource table is supported, check that no 852 * other one has been declared in a previously loaded 853 * firmware. 854 */ 855 if (ctx->rsc_pa || ctx->rsc_size) { 856 EMSG("More than one resource table found"); 857 res = TEE_ERROR_BAD_FORMAT; 858 goto out; 859 } 860 ctx->rsc_pa = rsc_pa; 861 ctx->rsc_size = rsc_size; 862 } else { 863 /* 864 * No resource table found. Force to TEE_SUCCESS as the 865 * resource table is optional. 866 */ 867 res = TEE_SUCCESS; 868 } 869 offset += img_size; 870 } 871 872 out: 873 /* Should we clean-up the memories in case of fail ? */ 874 TEE_Free(ctx->hash_table); 875 ctx->hash_table = NULL; 876 877 return res; 878 } 879 880 static TEE_Result remoteproc_load_fw(uint32_t pt, 881 TEE_Param params[TEE_NUM_PARAMS]) 882 { 883 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 884 TEE_PARAM_TYPE_MEMREF_INPUT, 885 TEE_PARAM_TYPE_NONE, 886 TEE_PARAM_TYPE_NONE); 887 struct remoteproc_context *ctx = NULL; 888 uint32_t rproc_id = params[0].value.a; 889 TEE_Result res = TEE_ERROR_GENERIC; 890 891 if (pt != exp_pt) 892 return TEE_ERROR_BAD_PARAMETERS; 893 894 ctx = remoteproc_find_firmware(rproc_id); 895 if (!ctx) 896 ctx = remoteproc_add_firmware(rproc_id); 897 if (!ctx) 898 return TEE_ERROR_OUT_OF_MEMORY; 899 900 /* The firmware is already loaded, do nothing */ 901 if (ctx->state == REMOTEPROC_LOADED) 902 return TEE_SUCCESS; 903 904 if (ctx->state != REMOTEPROC_OFF) 905 return TEE_ERROR_BAD_STATE; 906 907 if (!params[1].memref.buffer || !params[1].memref.size) 908 return TEE_ERROR_BAD_PARAMETERS; 909 910 DMSG("Got base addr: %p size %#zx", params[1].memref.buffer, 911 params[1].memref.size); 912 913 res = remoteproc_verify_firmware(ctx, params[1].memref.buffer, 914 params[1].memref.size); 915 if (res) { 916 EMSG("Can't Authenticate the firmware (res = %#"PRIx32")", res); 917 goto out; 918 } 919 920 res = remoteproc_load_elf(ctx); 921 if (res) 922 goto out; 923 924 ctx->state = REMOTEPROC_LOADED; 925 926 out: 927 /* Clear reference to firmware image from shared memory */ 928 ctx->fw_img = NULL; 929 ctx->fw_img_sz = 0; 930 ctx->nb_segment = 0; 931 932 /* Free allocated memories */ 933 TEE_Free(ctx->sec_cpy); 934 ctx->sec_cpy = NULL; 935 936 return res; 937 } 938 939 static TEE_Result remoteproc_start_fw(uint32_t pt, 940 TEE_Param params[TEE_NUM_PARAMS]) 941 { 942 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 943 TEE_PARAM_TYPE_NONE, 944 TEE_PARAM_TYPE_NONE, 945 TEE_PARAM_TYPE_NONE); 946 struct remoteproc_context *ctx = NULL; 947 uint32_t rproc_id = params[0].value.a; 948 TEE_Result res = TEE_ERROR_GENERIC; 949 950 if (pt != exp_pt) 951 return TEE_ERROR_BAD_PARAMETERS; 952 953 ctx = remoteproc_find_firmware(rproc_id); 954 if (!ctx) 955 return TEE_ERROR_BAD_PARAMETERS; 956 957 switch (ctx->state) { 958 case REMOTEPROC_OFF: 959 res = TEE_ERROR_BAD_STATE; 960 break; 961 case REMOTEPROC_STARTED: 962 res = TEE_SUCCESS; 963 break; 964 case REMOTEPROC_LOADED: 965 res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, 966 PTA_RPROC_FIRMWARE_START, 967 pt, params, NULL); 968 if (res == TEE_SUCCESS) 969 ctx->state = REMOTEPROC_STARTED; 970 break; 971 default: 972 res = TEE_ERROR_BAD_STATE; 973 } 974 975 return res; 976 } 977 978 static TEE_Result remoteproc_stop_fw(uint32_t pt, 979 TEE_Param params[TEE_NUM_PARAMS]) 980 { 981 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 982 TEE_PARAM_TYPE_NONE, 983 TEE_PARAM_TYPE_NONE, 984 TEE_PARAM_TYPE_NONE); 985 struct remoteproc_context *ctx = NULL; 986 uint32_t rproc_id = params[0].value.a; 987 TEE_Result res = TEE_ERROR_GENERIC; 988 989 if (pt != exp_pt) 990 return TEE_ERROR_BAD_PARAMETERS; 991 992 ctx = remoteproc_find_firmware(rproc_id); 993 if (!ctx) 994 return TEE_ERROR_BAD_PARAMETERS; 995 996 switch (ctx->state) { 997 case REMOTEPROC_LOADED: 998 res = TEE_ERROR_BAD_STATE; 999 break; 1000 case REMOTEPROC_OFF: 1001 res = TEE_SUCCESS; 1002 break; 1003 case REMOTEPROC_STARTED: 1004 res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, 1005 PTA_RPROC_FIRMWARE_STOP, 1006 pt, params, NULL); 1007 if (res == TEE_SUCCESS) 1008 ctx->state = REMOTEPROC_OFF; 1009 break; 1010 default: 1011 res = TEE_ERROR_BAD_STATE; 1012 } 1013 1014 return res; 1015 } 1016 1017 static TEE_Result remoteproc_get_rsc_table(uint32_t pt, 1018 TEE_Param params[TEE_NUM_PARAMS]) 1019 { 1020 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 1021 TEE_PARAM_TYPE_VALUE_OUTPUT, 1022 TEE_PARAM_TYPE_VALUE_OUTPUT, 1023 TEE_PARAM_TYPE_NONE); 1024 struct remoteproc_context *ctx = NULL; 1025 1026 if (pt != exp_pt) 1027 return TEE_ERROR_BAD_PARAMETERS; 1028 1029 ctx = remoteproc_find_firmware(params[0].value.a); 1030 if (!ctx) 1031 return TEE_ERROR_BAD_PARAMETERS; 1032 1033 if (ctx->state == REMOTEPROC_OFF) 1034 return TEE_ERROR_BAD_STATE; 1035 1036 reg_pair_from_64((uint64_t)ctx->rsc_pa, 1037 ¶ms[1].value.b, ¶ms[1].value.a); 1038 reg_pair_from_64((uint64_t)ctx->rsc_size, 1039 ¶ms[2].value.b, ¶ms[2].value.a); 1040 1041 return TEE_SUCCESS; 1042 } 1043 1044 static TEE_Result remoteproc_release_fw(uint32_t pt, 1045 TEE_Param params[TEE_NUM_PARAMS]) 1046 { 1047 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 1048 TEE_PARAM_TYPE_NONE, 1049 TEE_PARAM_TYPE_NONE, 1050 TEE_PARAM_TYPE_NONE); 1051 struct remoteproc_context *ctx = NULL; 1052 uint32_t rproc_id = params[0].value.a; 1053 TEE_Result res = TEE_ERROR_GENERIC; 1054 1055 if (pt != exp_pt) 1056 return TEE_ERROR_BAD_PARAMETERS; 1057 1058 ctx = remoteproc_find_firmware(rproc_id); 1059 if (!ctx) 1060 return TEE_ERROR_BAD_PARAMETERS; 1061 1062 if (ctx->state == REMOTEPROC_STARTED) 1063 return TEE_ERROR_BAD_STATE; 1064 1065 res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, 1066 PTA_REMOTEPROC_RELEASE, pt, params, NULL); 1067 if (res == TEE_SUCCESS) 1068 ctx->state = REMOTEPROC_OFF; 1069 1070 return res; 1071 } 1072 1073 TEE_Result TA_CreateEntryPoint(void) 1074 { 1075 return TEE_SUCCESS; 1076 } 1077 1078 void TA_DestroyEntryPoint(void) 1079 { 1080 } 1081 1082 /* 1083 * TA_OpenSessionEntryPoint: open a TA session associated to a remote processor 1084 * to manage. 1085 * 1086 * [in] params[0].value.a: Unique 32bit remote processor identifier 1087 */ 1088 TEE_Result TA_OpenSessionEntryPoint(uint32_t pt, 1089 TEE_Param params[TEE_NUM_PARAMS], 1090 void **sess __unused) 1091 { 1092 static const TEE_UUID uuid = PTA_RPROC_UUID; 1093 TEE_Result res = TEE_ERROR_GENERIC; 1094 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 1095 TEE_PARAM_TYPE_NONE, 1096 TEE_PARAM_TYPE_NONE, 1097 TEE_PARAM_TYPE_NONE); 1098 1099 if (pt != exp_pt) 1100 return TEE_ERROR_BAD_PARAMETERS; 1101 1102 if (!session_refcount) { 1103 res = TEE_OpenTASession(&uuid, TEE_TIMEOUT_INFINITE, pt, params, 1104 &pta_session, NULL); 1105 if (res) 1106 return res; 1107 } 1108 1109 session_refcount++; 1110 1111 return TEE_SUCCESS; 1112 } 1113 1114 void TA_CloseSessionEntryPoint(void *sess __unused) 1115 { 1116 session_refcount--; 1117 1118 if (!session_refcount) 1119 TEE_CloseTASession(pta_session); 1120 } 1121 1122 TEE_Result TA_InvokeCommandEntryPoint(void *sess __unused, uint32_t cmd_id, 1123 uint32_t pt, 1124 TEE_Param params[TEE_NUM_PARAMS]) 1125 { 1126 switch (cmd_id) { 1127 case TA_RPROC_CMD_LOAD_FW: 1128 return remoteproc_load_fw(pt, params); 1129 case TA_RPROC_CMD_START_FW: 1130 return remoteproc_start_fw(pt, params); 1131 case TA_RPROC_CMD_STOP_FW: 1132 return remoteproc_stop_fw(pt, params); 1133 case TA_RPROC_CMD_GET_RSC_TABLE: 1134 return remoteproc_get_rsc_table(pt, params); 1135 case TA_RPROC_CMD_GET_COREDUMP: 1136 return TEE_ERROR_NOT_IMPLEMENTED; 1137 case TA_RPROC_CMD_RELEASE_FW: 1138 return remoteproc_release_fw(pt, params); 1139 default: 1140 return TEE_ERROR_BAD_PARAMETERS; 1141 } 1142 } 1143