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 236 *value = NULL; 237 *length = 0; 238 239 /* Parse the TLV area */ 240 while (p_tlv < p_end_tlv) { 241 memcpy(&tlv_v, p_tlv, sizeof(tlv_v)); 242 tlv_type = TEE_U32_FROM_LITTLE_ENDIAN(tlv_v); 243 memcpy(&tlv_v, p_tlv + RPROC_TLV_LENGTH_OF, sizeof(tlv_v)); 244 tlv_length = TEE_U32_FROM_LITTLE_ENDIAN(tlv_v); 245 if (tlv_type == type) { 246 /* The specified TLV has been found */ 247 DMSG("TLV type %#"PRIx32" found, size %#"PRIx32, 248 type, tlv_length); 249 *value = &p_tlv[RPROC_TLV_VALUE_OF]; 250 *length = tlv_length; 251 if (tlv_length) 252 return TEE_SUCCESS; 253 else 254 return TEE_ERROR_NO_DATA; 255 } 256 p_tlv += ROUNDUP_64(sizeof(struct remoteproc_tlv) + tlv_length); 257 } 258 259 return TEE_ERROR_NO_DATA; 260 } 261 262 static struct remoteproc_context *remoteproc_find_firmware(uint32_t rproc_id) 263 { 264 struct remoteproc_context *ctx = NULL; 265 266 TAILQ_FOREACH(ctx, &firmware_head, link) 267 if (ctx->rproc_id == rproc_id) 268 return ctx; 269 270 return NULL; 271 } 272 273 static struct remoteproc_context *remoteproc_add_firmware(uint32_t rproc_id) 274 { 275 struct remoteproc_context *ctx = NULL; 276 277 ctx = TEE_Malloc(sizeof(*ctx), TEE_MALLOC_FILL_ZERO); 278 if (!ctx) 279 return NULL; 280 281 ctx->rproc_id = rproc_id; 282 283 TAILQ_INSERT_TAIL(&firmware_head, ctx, link); 284 285 return ctx; 286 } 287 288 static const struct remoteproc_sig_algo *remoteproc_get_algo(uint32_t sign_type) 289 { 290 unsigned int i = 0; 291 292 for (i = 0; i < ARRAY_SIZE(rproc_ta_sign_algo); i++) 293 if (sign_type == rproc_ta_sign_algo[i].sign_type) 294 return &rproc_ta_sign_algo[i]; 295 296 return NULL; 297 } 298 299 static TEE_Result remoteproc_pta_verify(struct remoteproc_context *ctx, 300 const struct remoteproc_sig_algo *algo, 301 uint8_t *hash, uint32_t hash_len) 302 { 303 TEE_Result res = TEE_ERROR_GENERIC; 304 struct remoteproc_fw_hdr *hdr = (void *)ctx->sec_cpy; 305 struct rproc_pta_key_info *keyinfo = NULL; 306 uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 307 TEE_PARAM_TYPE_MEMREF_INPUT, 308 TEE_PARAM_TYPE_MEMREF_INPUT, 309 TEE_PARAM_TYPE_MEMREF_INPUT); 310 TEE_Param params[TEE_NUM_PARAMS] = { }; 311 size_t length = 0; 312 uint8_t *tlv_keyinfo = NULL; 313 uint8_t *sign = NULL; 314 315 res = remoteproc_get_tlv(ctx->tlvs, hdr->tlv_len, 316 RPROC_TLV_PKEYINFO, &tlv_keyinfo, 317 &length); 318 if (res != TEE_SUCCESS && res != TEE_ERROR_NO_DATA) 319 return res; 320 321 keyinfo = TEE_Malloc(sizeof(*keyinfo) + length, TEE_MALLOC_FILL_ZERO); 322 if (!keyinfo) 323 return TEE_ERROR_OUT_OF_MEMORY; 324 325 keyinfo->algo = algo->id; 326 keyinfo->info_size = length; 327 memcpy(keyinfo->info, tlv_keyinfo, length); 328 329 sign = FW_SIGN_PTR(ctx->sec_cpy, hdr); 330 331 params[0].value.a = ctx->rproc_id; 332 params[1].memref.buffer = keyinfo; 333 params[1].memref.size = rproc_pta_keyinfo_size(keyinfo); 334 params[2].memref.buffer = hash; 335 params[2].memref.size = hash_len; 336 params[3].memref.buffer = sign; 337 params[3].memref.size = hdr->sign_len; 338 339 res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, 340 PTA_RPROC_VERIFY_DIGEST, 341 param_types, params, NULL); 342 if (res != TEE_SUCCESS) 343 EMSG("Failed to verify signature, res = %#"PRIx32, res); 344 345 TEE_Free(keyinfo); 346 347 return res; 348 } 349 350 static TEE_Result 351 remoteproc_save_fw_header_and_tlvs(struct remoteproc_context *ctx, 352 void *fw_orig, uint32_t fw_orig_size) 353 { 354 struct remoteproc_fw_hdr *hdr = fw_orig; 355 uint32_t length = 0; 356 357 if (!IS_ALIGNED_WITH_TYPE(fw_orig, struct remoteproc_fw_hdr)) 358 return TEE_ERROR_BAD_PARAMETERS; 359 360 if (ADD_OVERFLOW(sizeof(*hdr), ROUNDUP_64(hdr->tlv_len), &length) || 361 ADD_OVERFLOW(length, ROUNDUP_64(hdr->sign_len), &length)) 362 return TEE_ERROR_BAD_PARAMETERS; 363 364 if (fw_orig_size <= length || !hdr->sign_len || !hdr->tlv_len) 365 return TEE_ERROR_BAD_PARAMETERS; 366 367 remoteproc_header_dump(hdr); 368 369 /* Copy the header, the TLVs and the signature in secure memory */ 370 ctx->sec_cpy = TEE_Malloc(length, TEE_MALLOC_FILL_ZERO); 371 if (!ctx->sec_cpy) 372 return TEE_ERROR_OUT_OF_MEMORY; 373 374 memcpy(ctx->sec_cpy, fw_orig, length); 375 376 return TEE_SUCCESS; 377 } 378 379 static TEE_Result remoteproc_verify_signature(struct remoteproc_context *ctx) 380 { 381 TEE_OperationHandle op = TEE_HANDLE_NULL; 382 struct remoteproc_fw_hdr *hdr = (void *)ctx->sec_cpy; 383 const struct remoteproc_sig_algo *algo = NULL; 384 TEE_Result res = TEE_ERROR_GENERIC; 385 uint8_t *tlv_sign_algo = NULL; 386 size_t length = 0; 387 uint8_t *hash = NULL; 388 size_t hash_len = 0; 389 390 /* Get the algo type from TLV data */ 391 res = remoteproc_get_tlv(ctx->tlvs, hdr->tlv_len, RPROC_TLV_SIGNTYPE, 392 &tlv_sign_algo, &length); 393 394 if (res != TEE_SUCCESS || length != RPROC_TLV_SIGNTYPE_LGTH) 395 return TEE_ERROR_BAD_PARAMETERS; 396 397 algo = remoteproc_get_algo(*tlv_sign_algo); 398 if (!algo) { 399 EMSG("Unsupported signature type %"PRId8, *tlv_sign_algo); 400 return TEE_ERROR_NOT_SUPPORTED; 401 } 402 403 /* Compute the header and TLVs hashes */ 404 hash_len = algo->hash_len; 405 hash = TEE_Malloc(hash_len, TEE_MALLOC_FILL_ZERO); 406 if (!hash) 407 return TEE_ERROR_OUT_OF_MEMORY; 408 409 res = TEE_AllocateOperation(&op, TEE_ALG_SHA256, TEE_MODE_DIGEST, 0); 410 if (res != TEE_SUCCESS) 411 goto free_hash; 412 413 TEE_DigestUpdate(op, hdr, sizeof(*hdr)); 414 res = TEE_DigestDoFinal(op, ctx->tlvs, ROUNDUP_64(hdr->tlv_len), 415 hash, &hash_len); 416 417 if (res != TEE_SUCCESS) 418 goto out; 419 420 /* 421 * This implementation could be enhanced by providing alternative to 422 * verify the signature in the TA. This could be done for instance by 423 * getting the key object from secure storage. 424 */ 425 426 /* By default ask the remoteproc PTA to verify the signature. */ 427 res = remoteproc_pta_verify(ctx, algo, hash, hash_len); 428 429 out: 430 TEE_FreeOperation(op); 431 free_hash: 432 TEE_Free(hash); 433 434 return res; 435 } 436 437 static TEE_Result remoteproc_verify_header(struct remoteproc_context *ctx, 438 uint32_t fw_orig_size) 439 { 440 struct remoteproc_fw_hdr *hdr = (void *)ctx->sec_cpy; 441 uint32_t size = 0; 442 443 if (hdr->magic != RPROC_HDR_MAGIC) 444 return TEE_ERROR_BAD_PARAMETERS; 445 446 if (hdr->version != HEADER_VERSION) 447 return TEE_ERROR_BAD_PARAMETERS; 448 449 /* 450 * The offsets are aligned to 64 bits format. While the length of each 451 * chunks are the effective length, excluding the alignment padding 452 * bytes. 453 */ 454 if (ADD_OVERFLOW(sizeof(*hdr), ROUNDUP_64(hdr->sign_len), &size) || 455 ADD_OVERFLOW(size, ROUNDUP_64(hdr->img_len), &size) || 456 ADD_OVERFLOW(size, ROUNDUP_64(hdr->tlv_len), &size) || 457 fw_orig_size != size) 458 return TEE_ERROR_BAD_PARAMETERS; 459 460 return TEE_SUCCESS; 461 } 462 463 static TEE_Result get_rproc_pta_capabilities(struct remoteproc_context *ctx) 464 { 465 uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 466 TEE_PARAM_TYPE_VALUE_OUTPUT, 467 TEE_PARAM_TYPE_VALUE_OUTPUT, 468 TEE_PARAM_TYPE_NONE); 469 TEE_Param params[TEE_NUM_PARAMS] = { }; 470 TEE_Result res = TEE_ERROR_GENERIC; 471 472 params[0].value.a = ctx->rproc_id; 473 474 res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, 475 PTA_RPROC_HW_CAPABILITIES, 476 param_types, params, NULL); 477 if (res) 478 return res; 479 480 ctx->hw_fmt = params[1].value.a; 481 ctx->hw_img_prot = params[2].value.a; 482 483 return TEE_SUCCESS; 484 } 485 486 static TEE_Result remoteproc_verify_firmware(struct remoteproc_context *ctx, 487 uint8_t *fw_orig, 488 uint32_t fw_orig_size) 489 { 490 struct remoteproc_fw_hdr *hdr = NULL; 491 TEE_Result res = TEE_ERROR_GENERIC; 492 493 res = get_rproc_pta_capabilities(ctx); 494 if (res) 495 return res; 496 497 /* Secure the firmware image depending on strategy */ 498 if (!(ctx->hw_img_prot & PTA_RPROC_HWCAP_PROT_HASH_TABLE) || 499 ctx->hw_fmt != PTA_RPROC_HWCAP_FMT_ELF) { 500 /* 501 * Only hash table for ELF format support implemented 502 * in a first step. 503 */ 504 return TEE_ERROR_NOT_IMPLEMENTED; 505 } 506 507 res = remoteproc_save_fw_header_and_tlvs(ctx, fw_orig, fw_orig_size); 508 if (res) 509 return res; 510 511 res = remoteproc_verify_header(ctx, fw_orig_size); 512 if (res) 513 goto free_sec_cpy; 514 515 hdr = (void *)ctx->sec_cpy; 516 ctx->tlvs_sz = hdr->tlv_len; 517 ctx->tlvs = FW_TLV_PTR(ctx->sec_cpy, hdr); 518 519 res = remoteproc_verify_signature(ctx); 520 if (res) 521 goto free_sec_cpy; 522 523 /* Store location of the loadable binary in non-secure memory */ 524 ctx->fw_img_sz = hdr->img_len; 525 ctx->fw_img = FW_IMG_PTR(fw_orig, hdr); 526 527 DMSG("Firmware images addr: %p size: %zu", ctx->fw_img, 528 ctx->fw_img_sz); 529 530 return TEE_SUCCESS; 531 532 free_sec_cpy: 533 TEE_Free(ctx->sec_cpy); 534 ctx->sec_cpy = NULL; 535 536 return res; 537 } 538 539 static paddr_t remoteproc_da_to_pa(uint32_t da, size_t size, 540 struct remoteproc_context *ctx) 541 { 542 uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 543 TEE_PARAM_TYPE_VALUE_INPUT, 544 TEE_PARAM_TYPE_VALUE_INPUT, 545 TEE_PARAM_TYPE_VALUE_OUTPUT); 546 TEE_Param params[TEE_NUM_PARAMS] = { }; 547 TEE_Result res = TEE_ERROR_GENERIC; 548 paddr_t pa = 0; 549 550 /* 551 * The ELF file contains remote processor device addresses, that refer 552 * to the remote processor memory space. 553 * A translation is needed to get the corresponding physical address. 554 */ 555 556 params[0].value.a = ctx->rproc_id; 557 params[1].value.a = da; 558 params[2].value.a = size; 559 560 res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, 561 PTA_RPROC_FIRMWARE_DA_TO_PA, 562 param_types, params, NULL); 563 if (res != TEE_SUCCESS) { 564 EMSG("Failed to translate device address %#"PRIx32, da); 565 return 0; 566 } 567 568 pa = (paddr_t)reg_pair_to_64(params[3].value.b, params[3].value.a); 569 570 /* Assert that the pa address is not 0 */ 571 assert(pa); 572 573 return pa; 574 } 575 576 static TEE_Result remoteproc_parse_rsc_table(struct remoteproc_context *ctx, 577 uint8_t *fw_img, size_t fw_img_sz, 578 paddr_t *rsc_pa, 579 size_t *rsc_size) 580 { 581 uint32_t da = 0; 582 TEE_Result res = TEE_ERROR_GENERIC; 583 Elf32_Word size = 0; 584 585 res = e32_parser_find_rsc_table(fw_img, fw_img_sz, &da, &size); 586 if (res) 587 return res; 588 589 DMSG("Resource table device address %#"PRIx32" size %#"PRIx32, 590 da, size); 591 592 *rsc_pa = remoteproc_da_to_pa(da, size, ctx); 593 if (!*rsc_pa) 594 return TEE_ERROR_ACCESS_DENIED; 595 596 *rsc_size = size; 597 598 return TEE_SUCCESS; 599 } 600 601 static TEE_Result get_hash_table(struct remoteproc_context *ctx) 602 { 603 TEE_Result res = TEE_ERROR_GENERIC; 604 uint8_t *tlv_hash = NULL; 605 struct remoteproc_segment *hash_table = NULL; 606 size_t length = 0; 607 608 /* Get the segment's hash table from TLV data */ 609 res = remoteproc_get_tlv(ctx->tlvs, ctx->tlvs_sz, RPROC_TLV_HASHTABLE, 610 &tlv_hash, &length); 611 if (res) 612 return res; 613 614 if (length % sizeof(struct remoteproc_segment)) 615 return TEE_ERROR_BAD_PARAMETERS; 616 617 /* We can not ensure that tlv_hash is memory aligned so make a copy */ 618 hash_table = TEE_Malloc(length, TEE_MALLOC_FILL_ZERO); 619 if (!hash_table) 620 return TEE_ERROR_OUT_OF_MEMORY; 621 622 memcpy(hash_table, tlv_hash, length); 623 624 ctx->hash_table = hash_table; 625 ctx->nb_segment = length / sizeof(struct remoteproc_segment); 626 627 return TEE_SUCCESS; 628 } 629 630 static TEE_Result get_tlv_images_type(struct remoteproc_context *ctx, 631 uint8_t num_img, uint8_t idx, 632 uint8_t *img_type) 633 { 634 TEE_Result res = TEE_ERROR_GENERIC; 635 uint8_t *tlv_value = NULL; 636 size_t length = 0; 637 638 /* Get the type of the image to load, from TLV data */ 639 res = remoteproc_get_tlv(ctx->tlvs, ctx->tlvs_sz, RPROC_TLV_IMGTYPE, 640 &tlv_value, &length); 641 if (res) 642 return res; 643 644 if (length != (sizeof(*img_type) * num_img)) 645 return TEE_ERROR_BAD_PARAMETERS; 646 647 *img_type = tlv_value[idx]; 648 649 return TEE_SUCCESS; 650 } 651 652 static TEE_Result get_tlv_images_size(struct remoteproc_context *ctx, 653 uint8_t num_img, uint8_t idx, 654 uint32_t *img_size) 655 { 656 TEE_Result res = TEE_ERROR_GENERIC; 657 uint8_t *tlv_value = NULL; 658 uint32_t tlv_v = 0; 659 size_t length = 0; 660 661 /* Get the size of the image to load, from TLV data */ 662 res = remoteproc_get_tlv(ctx->tlvs, ctx->tlvs_sz, RPROC_TLV_IMGSIZE, 663 &tlv_value, &length); 664 if (res) 665 return res; 666 667 if (length != (sizeof(*img_size) * num_img)) 668 return TEE_ERROR_BAD_PARAMETERS; 669 670 memcpy(&tlv_v, &tlv_value[sizeof(*img_size) * idx], sizeof(tlv_v)); 671 *img_size = TEE_U32_FROM_LITTLE_ENDIAN(tlv_v); 672 673 return TEE_SUCCESS; 674 } 675 676 static TEE_Result get_segment_hash(struct remoteproc_context *ctx, uint8_t *src, 677 uint32_t size, uint32_t da, 678 uint32_t mem_size, uint8_t **hash) 679 { 680 struct remoteproc_segment *peh = NULL; 681 unsigned int i = 0; 682 unsigned int nb_entry = ctx->nb_segment; 683 684 peh = (void *)(ctx->hash_table); 685 686 for (i = 0; i < nb_entry; peh++, i++) { 687 if (peh->phdr.p_paddr != da) 688 continue; 689 690 /* 691 * Segment metadata are read from a non-secure memory. 692 * Validate them using hash table data stored in secure memory. 693 */ 694 if (peh->phdr.p_type != PT_LOAD) 695 return TEE_ERROR_BAD_PARAMETERS; 696 697 if (peh->phdr.p_filesz != size || peh->phdr.p_memsz != mem_size) 698 return TEE_ERROR_BAD_PARAMETERS; 699 700 if (src < ctx->fw_img || 701 src > (ctx->fw_img + ctx->fw_img_sz) || 702 (src + peh->phdr.p_filesz) > (ctx->fw_img + ctx->fw_img_sz)) 703 return TEE_ERROR_BAD_PARAMETERS; 704 705 *hash = peh->hash; 706 707 return TEE_SUCCESS; 708 } 709 710 return TEE_ERROR_NO_DATA; 711 } 712 713 static TEE_Result remoteproc_load_segment(uint8_t *src, uint32_t size, 714 uint32_t da, uint32_t mem_size, 715 void *priv) 716 { 717 struct remoteproc_context *ctx = priv; 718 uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 719 TEE_PARAM_TYPE_MEMREF_INPUT, 720 TEE_PARAM_TYPE_VALUE_INPUT, 721 TEE_PARAM_TYPE_MEMREF_INPUT); 722 TEE_Param params[TEE_NUM_PARAMS] = { }; 723 TEE_Result res = TEE_ERROR_GENERIC; 724 uint8_t *hash = NULL; 725 726 /* 727 * Invoke platform remoteproc PTA to load the segment in remote 728 * processor memory which is not mapped in the TA space. 729 */ 730 731 DMSG("Load segment %#"PRIx32" size %"PRIu32" (%"PRIu32")", da, size, 732 mem_size); 733 734 res = get_segment_hash(ctx, src, size, da, mem_size, &hash); 735 if (res) 736 return res; 737 738 params[0].value.a = ctx->rproc_id; 739 params[1].memref.buffer = src; 740 params[1].memref.size = size; 741 params[2].value.a = da; 742 params[3].memref.buffer = hash; 743 params[3].memref.size = TEE_SHA256_HASH_SIZE; 744 745 if (size) { 746 res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, 747 PTA_RPROC_LOAD_SEGMENT_SHA256, 748 param_types, params, NULL); 749 if (res != TEE_SUCCESS) { 750 EMSG("Fails to load segment, res = 0x%#"PRIx32, res); 751 return res; 752 } 753 } 754 755 /* Fill the rest of the memory with 0 */ 756 if (size < mem_size) { 757 param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 758 TEE_PARAM_TYPE_VALUE_INPUT, 759 TEE_PARAM_TYPE_VALUE_INPUT, 760 TEE_PARAM_TYPE_VALUE_INPUT); 761 params[1].value.a = da + size; 762 params[2].value.a = mem_size - size; 763 params[3].value.a = 0; 764 765 res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, 766 PTA_RPROC_SET_MEMORY, 767 param_types, params, NULL); 768 if (res != TEE_SUCCESS) 769 EMSG("Fails to clear segment, res = %#"PRIx32, res); 770 } 771 772 return res; 773 } 774 775 static TEE_Result remoteproc_load_elf(struct remoteproc_context *ctx) 776 { 777 TEE_Result res = TEE_ERROR_GENERIC; 778 unsigned int num_img = 0; 779 unsigned int i = 0; 780 uint8_t img_type = REMOTEPROC_INVALID_TYPE; 781 uint32_t img_size = 0; 782 uint8_t *tlv = NULL; 783 int32_t offset = 0; 784 size_t length = 0; 785 paddr_t rsc_pa = 0; 786 size_t rsc_size = 0; 787 788 res = e32_parse_ehdr(ctx->fw_img, ctx->fw_img_sz); 789 if (res) { 790 EMSG("Failed to parse firmware, res = %#"PRIx32, res); 791 return res; 792 } 793 794 res = get_hash_table(ctx); 795 if (res) 796 return res; 797 798 /* Get the number of firmware images to load */ 799 res = remoteproc_get_tlv(ctx->tlvs, ctx->tlvs_sz, RPROC_TLV_NUM_IMG, 800 &tlv, &length); 801 if (res) 802 goto out; 803 if (length != sizeof(uint8_t)) { 804 res = TEE_ERROR_BAD_FORMAT; 805 goto out; 806 } 807 808 num_img = *tlv; 809 if (!num_img) { 810 res = TEE_ERROR_NO_DATA; 811 goto out; 812 } 813 814 /* 815 * Initialize resource table with zero. These values will be returned if 816 * no optional resource table is found in images. 817 */ 818 ctx->rsc_pa = 0; 819 ctx->rsc_size = 0; 820 821 for (i = 0; i < num_img; i++) { 822 res = get_tlv_images_type(ctx, num_img, i, &img_type); 823 if (res) 824 goto out; 825 if (img_type != REMOTEPROC_ELF_TYPE) { 826 res = TEE_ERROR_BAD_FORMAT; 827 goto out; 828 } 829 830 res = get_tlv_images_size(ctx, num_img, i, &img_size); 831 if (res) 832 goto out; 833 834 res = e32_parser_load_elf_image(ctx->fw_img + offset, img_size, 835 remoteproc_load_segment, ctx); 836 if (res) 837 goto out; 838 839 /* Take opportunity to get the resource table address */ 840 res = remoteproc_parse_rsc_table(ctx, ctx->fw_img + offset, 841 img_size, &rsc_pa, &rsc_size); 842 if (res != TEE_SUCCESS && res != TEE_ERROR_NO_DATA) 843 goto out; 844 845 if (res == TEE_SUCCESS) { 846 /* 847 * Only one resource table is supported, check that no 848 * other one has been declared in a previously loaded 849 * firmware. 850 */ 851 if (ctx->rsc_pa || ctx->rsc_size) { 852 EMSG("More than one resource table found"); 853 res = TEE_ERROR_BAD_FORMAT; 854 goto out; 855 } 856 ctx->rsc_pa = rsc_pa; 857 ctx->rsc_size = rsc_size; 858 } else { 859 /* 860 * No resource table found. Force to TEE_SUCCESS as the 861 * resource table is optional. 862 */ 863 res = TEE_SUCCESS; 864 } 865 offset += img_size; 866 } 867 868 out: 869 /* Should we clean-up the memories in case of fail ? */ 870 TEE_Free(ctx->hash_table); 871 ctx->hash_table = NULL; 872 873 return res; 874 } 875 876 static TEE_Result remoteproc_load_fw(uint32_t pt, 877 TEE_Param params[TEE_NUM_PARAMS]) 878 { 879 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 880 TEE_PARAM_TYPE_MEMREF_INPUT, 881 TEE_PARAM_TYPE_NONE, 882 TEE_PARAM_TYPE_NONE); 883 struct remoteproc_context *ctx = NULL; 884 uint32_t rproc_id = params[0].value.a; 885 TEE_Result res = TEE_ERROR_GENERIC; 886 887 if (pt != exp_pt) 888 return TEE_ERROR_BAD_PARAMETERS; 889 890 ctx = remoteproc_find_firmware(rproc_id); 891 if (!ctx) 892 ctx = remoteproc_add_firmware(rproc_id); 893 if (!ctx) 894 return TEE_ERROR_OUT_OF_MEMORY; 895 896 /* The firmware is already loaded, do nothing */ 897 if (ctx->state == REMOTEPROC_LOADED) 898 return TEE_SUCCESS; 899 900 if (ctx->state != REMOTEPROC_OFF) 901 return TEE_ERROR_BAD_STATE; 902 903 if (!params[1].memref.buffer || !params[1].memref.size) 904 return TEE_ERROR_BAD_PARAMETERS; 905 906 DMSG("Got base addr: %p size %#zx", params[1].memref.buffer, 907 params[1].memref.size); 908 909 res = remoteproc_verify_firmware(ctx, params[1].memref.buffer, 910 params[1].memref.size); 911 if (res) { 912 EMSG("Can't Authenticate the firmware (res = %#"PRIx32")", res); 913 goto out; 914 } 915 916 res = remoteproc_load_elf(ctx); 917 if (res) 918 goto out; 919 920 ctx->state = REMOTEPROC_LOADED; 921 922 out: 923 /* Clear reference to firmware image from shared memory */ 924 ctx->fw_img = NULL; 925 ctx->fw_img_sz = 0; 926 ctx->nb_segment = 0; 927 928 /* Free allocated memories */ 929 TEE_Free(ctx->sec_cpy); 930 ctx->sec_cpy = NULL; 931 932 return res; 933 } 934 935 static TEE_Result remoteproc_start_fw(uint32_t pt, 936 TEE_Param params[TEE_NUM_PARAMS]) 937 { 938 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 939 TEE_PARAM_TYPE_NONE, 940 TEE_PARAM_TYPE_NONE, 941 TEE_PARAM_TYPE_NONE); 942 struct remoteproc_context *ctx = NULL; 943 uint32_t rproc_id = params[0].value.a; 944 TEE_Result res = TEE_ERROR_GENERIC; 945 946 if (pt != exp_pt) 947 return TEE_ERROR_BAD_PARAMETERS; 948 949 ctx = remoteproc_find_firmware(rproc_id); 950 if (!ctx) 951 return TEE_ERROR_BAD_PARAMETERS; 952 953 switch (ctx->state) { 954 case REMOTEPROC_OFF: 955 res = TEE_ERROR_BAD_STATE; 956 break; 957 case REMOTEPROC_STARTED: 958 res = TEE_SUCCESS; 959 break; 960 case REMOTEPROC_LOADED: 961 res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, 962 PTA_RPROC_FIRMWARE_START, 963 pt, params, NULL); 964 if (res == TEE_SUCCESS) 965 ctx->state = REMOTEPROC_STARTED; 966 break; 967 default: 968 res = TEE_ERROR_BAD_STATE; 969 } 970 971 return res; 972 } 973 974 static TEE_Result remoteproc_stop_fw(uint32_t pt, 975 TEE_Param params[TEE_NUM_PARAMS]) 976 { 977 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 978 TEE_PARAM_TYPE_NONE, 979 TEE_PARAM_TYPE_NONE, 980 TEE_PARAM_TYPE_NONE); 981 struct remoteproc_context *ctx = NULL; 982 uint32_t rproc_id = params[0].value.a; 983 TEE_Result res = TEE_ERROR_GENERIC; 984 985 if (pt != exp_pt) 986 return TEE_ERROR_BAD_PARAMETERS; 987 988 ctx = remoteproc_find_firmware(rproc_id); 989 if (!ctx) 990 return TEE_ERROR_BAD_PARAMETERS; 991 992 switch (ctx->state) { 993 case REMOTEPROC_LOADED: 994 res = TEE_ERROR_BAD_STATE; 995 break; 996 case REMOTEPROC_OFF: 997 res = TEE_SUCCESS; 998 break; 999 case REMOTEPROC_STARTED: 1000 res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, 1001 PTA_RPROC_FIRMWARE_STOP, 1002 pt, params, NULL); 1003 if (res == TEE_SUCCESS) 1004 ctx->state = REMOTEPROC_OFF; 1005 break; 1006 default: 1007 res = TEE_ERROR_BAD_STATE; 1008 } 1009 1010 return res; 1011 } 1012 1013 static TEE_Result remoteproc_get_rsc_table(uint32_t pt, 1014 TEE_Param params[TEE_NUM_PARAMS]) 1015 { 1016 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 1017 TEE_PARAM_TYPE_VALUE_OUTPUT, 1018 TEE_PARAM_TYPE_VALUE_OUTPUT, 1019 TEE_PARAM_TYPE_NONE); 1020 struct remoteproc_context *ctx = NULL; 1021 1022 if (pt != exp_pt) 1023 return TEE_ERROR_BAD_PARAMETERS; 1024 1025 ctx = remoteproc_find_firmware(params[0].value.a); 1026 if (!ctx) 1027 return TEE_ERROR_BAD_PARAMETERS; 1028 1029 if (ctx->state == REMOTEPROC_OFF) 1030 return TEE_ERROR_BAD_STATE; 1031 1032 reg_pair_from_64((uint64_t)ctx->rsc_pa, 1033 ¶ms[1].value.b, ¶ms[1].value.a); 1034 reg_pair_from_64((uint64_t)ctx->rsc_size, 1035 ¶ms[2].value.b, ¶ms[2].value.a); 1036 1037 return TEE_SUCCESS; 1038 } 1039 1040 static TEE_Result remoteproc_release_fw(uint32_t pt, 1041 TEE_Param params[TEE_NUM_PARAMS]) 1042 { 1043 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 1044 TEE_PARAM_TYPE_NONE, 1045 TEE_PARAM_TYPE_NONE, 1046 TEE_PARAM_TYPE_NONE); 1047 struct remoteproc_context *ctx = NULL; 1048 uint32_t rproc_id = params[0].value.a; 1049 TEE_Result res = TEE_ERROR_GENERIC; 1050 1051 if (pt != exp_pt) 1052 return TEE_ERROR_BAD_PARAMETERS; 1053 1054 ctx = remoteproc_find_firmware(rproc_id); 1055 if (!ctx) 1056 return TEE_ERROR_BAD_PARAMETERS; 1057 1058 if (ctx->state == REMOTEPROC_STARTED) 1059 return TEE_ERROR_BAD_STATE; 1060 1061 res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, 1062 PTA_REMOTEPROC_RELEASE, pt, params, NULL); 1063 if (res == TEE_SUCCESS) 1064 ctx->state = REMOTEPROC_OFF; 1065 1066 return res; 1067 } 1068 1069 TEE_Result TA_CreateEntryPoint(void) 1070 { 1071 return TEE_SUCCESS; 1072 } 1073 1074 void TA_DestroyEntryPoint(void) 1075 { 1076 } 1077 1078 /* 1079 * TA_OpenSessionEntryPoint: open a TA session associated to a remote processor 1080 * to manage. 1081 * 1082 * [in] params[0].value.a: Unique 32bit remote processor identifier 1083 */ 1084 TEE_Result TA_OpenSessionEntryPoint(uint32_t pt, 1085 TEE_Param params[TEE_NUM_PARAMS], 1086 void **sess __unused) 1087 { 1088 static const TEE_UUID uuid = PTA_RPROC_UUID; 1089 TEE_Result res = TEE_ERROR_GENERIC; 1090 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 1091 TEE_PARAM_TYPE_NONE, 1092 TEE_PARAM_TYPE_NONE, 1093 TEE_PARAM_TYPE_NONE); 1094 1095 if (pt != exp_pt) 1096 return TEE_ERROR_BAD_PARAMETERS; 1097 1098 if (!session_refcount) { 1099 res = TEE_OpenTASession(&uuid, TEE_TIMEOUT_INFINITE, pt, params, 1100 &pta_session, NULL); 1101 if (res) 1102 return res; 1103 } 1104 1105 session_refcount++; 1106 1107 return TEE_SUCCESS; 1108 } 1109 1110 void TA_CloseSessionEntryPoint(void *sess __unused) 1111 { 1112 session_refcount--; 1113 1114 if (!session_refcount) 1115 TEE_CloseTASession(pta_session); 1116 } 1117 1118 TEE_Result TA_InvokeCommandEntryPoint(void *sess __unused, uint32_t cmd_id, 1119 uint32_t pt, 1120 TEE_Param params[TEE_NUM_PARAMS]) 1121 { 1122 switch (cmd_id) { 1123 case TA_RPROC_CMD_LOAD_FW: 1124 return remoteproc_load_fw(pt, params); 1125 case TA_RPROC_CMD_START_FW: 1126 return remoteproc_start_fw(pt, params); 1127 case TA_RPROC_CMD_STOP_FW: 1128 return remoteproc_stop_fw(pt, params); 1129 case TA_RPROC_CMD_GET_RSC_TABLE: 1130 return remoteproc_get_rsc_table(pt, params); 1131 case TA_RPROC_CMD_GET_COREDUMP: 1132 return TEE_ERROR_NOT_IMPLEMENTED; 1133 case TA_RPROC_CMD_RELEASE_FW: 1134 return remoteproc_release_fw(pt, params); 1135 default: 1136 return TEE_ERROR_BAD_PARAMETERS; 1137 } 1138 } 1139