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