xref: /optee_os/ta/remoteproc/src/remoteproc_core.c (revision 68dc1d623b60c7b8c9e9776b1f810bee12c41f48)
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 			 &params[1].value.b, &params[1].value.a);
1038 	reg_pair_from_64((uint64_t)ctx->rsc_size,
1039 			 &params[2].value.b, &params[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