xref: /optee_os/core/pta/stm32mp/remoteproc_pta.c (revision 3ebb03495a1867462824f59ab4981125075f1351)
1f6c57ea4SArnaud Pouliquen // SPDX-License-Identifier: BSD-2-Clause
2f6c57ea4SArnaud Pouliquen /*
3f6c57ea4SArnaud Pouliquen  * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
4f6c57ea4SArnaud Pouliquen  */
5f6c57ea4SArnaud Pouliquen 
6f6c57ea4SArnaud Pouliquen #include <crypto/crypto.h>
7f6c57ea4SArnaud Pouliquen #include <drivers/clk.h>
8f6c57ea4SArnaud Pouliquen #include <drivers/rstctrl.h>
9f6c57ea4SArnaud Pouliquen #include <drivers/stm32_remoteproc.h>
10f6c57ea4SArnaud Pouliquen #include <drivers/stm32mp_dt_bindings.h>
11f6c57ea4SArnaud Pouliquen #include <drivers/stm32mp1_rcc.h>
12f6c57ea4SArnaud Pouliquen #include <initcall.h>
13f6c57ea4SArnaud Pouliquen #include <kernel/pseudo_ta.h>
14f6c57ea4SArnaud Pouliquen #include <kernel/user_ta.h>
15f6c57ea4SArnaud Pouliquen #include <remoteproc_pta.h>
16f6c57ea4SArnaud Pouliquen #include <string.h>
17f6c57ea4SArnaud Pouliquen 
18f6c57ea4SArnaud Pouliquen #include "rproc_pub_key.h"
19f6c57ea4SArnaud Pouliquen 
20f6c57ea4SArnaud Pouliquen #define PTA_NAME	"remoteproc.pta"
21f6c57ea4SArnaud Pouliquen 
22f6c57ea4SArnaud Pouliquen /*
23f6c57ea4SArnaud Pouliquen  * UUID of the remoteproc Trusted application authorized to communicate with
24f6c57ea4SArnaud Pouliquen  * the remoteproc pseudo TA. The UID should match the one defined in the
25f6c57ea4SArnaud Pouliquen  * ta_remoteproc.h header file.
26f6c57ea4SArnaud Pouliquen  */
27f6c57ea4SArnaud Pouliquen #define TA_REMOTEPROC_UUID \
28f6c57ea4SArnaud Pouliquen 	{ 0x80a4c275, 0x0a47, 0x4905, \
29f6c57ea4SArnaud Pouliquen 		{ 0x82, 0x85, 0x14, 0x86, 0xa9, 0x77, 0x1a, 0x08} }
30f6c57ea4SArnaud Pouliquen 
31f6c57ea4SArnaud Pouliquen /*
32f6c57ea4SArnaud Pouliquen  * Firmware states
33f6c57ea4SArnaud Pouliquen  * REMOTEPROC_OFF: firmware is off
34f6c57ea4SArnaud Pouliquen  * REMOTEPROC_ON: firmware is running
35f6c57ea4SArnaud Pouliquen  */
36f6c57ea4SArnaud Pouliquen enum rproc_load_state {
37f6c57ea4SArnaud Pouliquen 	REMOTEPROC_OFF = 0,
38f6c57ea4SArnaud Pouliquen 	REMOTEPROC_ON,
39f6c57ea4SArnaud Pouliquen };
40f6c57ea4SArnaud Pouliquen 
41f6c57ea4SArnaud Pouliquen /* Currently supporting a single remote processor instance */
42f6c57ea4SArnaud Pouliquen static enum rproc_load_state rproc_ta_state = REMOTEPROC_OFF;
43f6c57ea4SArnaud Pouliquen 
rproc_pta_capabilities(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])44f6c57ea4SArnaud Pouliquen static TEE_Result rproc_pta_capabilities(uint32_t pt,
45f6c57ea4SArnaud Pouliquen 					 TEE_Param params[TEE_NUM_PARAMS])
46f6c57ea4SArnaud Pouliquen {
47f6c57ea4SArnaud Pouliquen 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
48f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_VALUE_OUTPUT,
49f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_VALUE_OUTPUT,
50f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_NONE);
51f6c57ea4SArnaud Pouliquen 
52f6c57ea4SArnaud Pouliquen 	if (pt != exp_pt)
53f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_BAD_PARAMETERS;
54f6c57ea4SArnaud Pouliquen 
55f6c57ea4SArnaud Pouliquen 	if (!stm32_rproc_get(params[0].value.a))
56f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_NOT_SUPPORTED;
57f6c57ea4SArnaud Pouliquen 
58f6c57ea4SArnaud Pouliquen 	/* Support only ELF format */
59f6c57ea4SArnaud Pouliquen 	params[1].value.a = PTA_RPROC_HWCAP_FMT_ELF;
60f6c57ea4SArnaud Pouliquen 
61f6c57ea4SArnaud Pouliquen 	/*
62f6c57ea4SArnaud Pouliquen 	 * Due to stm32mp1 pager, secure memory is too expensive. Support hash
63f6c57ea4SArnaud Pouliquen 	 * protected image only, so that firmware image can be loaded from
64f6c57ea4SArnaud Pouliquen 	 * non-secure memory.
65f6c57ea4SArnaud Pouliquen 	 */
66f6c57ea4SArnaud Pouliquen 	params[2].value.a = PTA_RPROC_HWCAP_PROT_HASH_TABLE;
67f6c57ea4SArnaud Pouliquen 
68f6c57ea4SArnaud Pouliquen 	return TEE_SUCCESS;
69f6c57ea4SArnaud Pouliquen }
70f6c57ea4SArnaud Pouliquen 
rproc_pta_load_segment(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])71f6c57ea4SArnaud Pouliquen static TEE_Result rproc_pta_load_segment(uint32_t pt,
72f6c57ea4SArnaud Pouliquen 					 TEE_Param params[TEE_NUM_PARAMS])
73f6c57ea4SArnaud Pouliquen {
74f6c57ea4SArnaud Pouliquen 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
75f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_MEMREF_INPUT,
76f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_VALUE_INPUT,
77f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_MEMREF_INPUT);
78f6c57ea4SArnaud Pouliquen 	TEE_Result res = TEE_ERROR_GENERIC;
79f6c57ea4SArnaud Pouliquen 	paddr_t pa = 0;
80f6c57ea4SArnaud Pouliquen 	void *dst = NULL;
81f6c57ea4SArnaud Pouliquen 	uint8_t *src = params[1].memref.buffer;
82f6c57ea4SArnaud Pouliquen 	size_t size = params[1].memref.size;
83f6c57ea4SArnaud Pouliquen 	uint8_t *hash = params[3].memref.buffer;
84f6c57ea4SArnaud Pouliquen 	paddr_t da = (paddr_t)reg_pair_to_64(params[2].value.b,
85f6c57ea4SArnaud Pouliquen 					     params[2].value.a);
86f6c57ea4SArnaud Pouliquen 
87f6c57ea4SArnaud Pouliquen 	if (pt != exp_pt)
88f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_BAD_PARAMETERS;
89f6c57ea4SArnaud Pouliquen 
90f6c57ea4SArnaud Pouliquen 	if (!hash || params[3].memref.size != TEE_SHA256_HASH_SIZE)
91f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_BAD_PARAMETERS;
92f6c57ea4SArnaud Pouliquen 
93f6c57ea4SArnaud Pouliquen 	if (rproc_ta_state != REMOTEPROC_OFF)
94f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_BAD_STATE;
95f6c57ea4SArnaud Pouliquen 
96f6c57ea4SArnaud Pouliquen 	/* Get the physical address in local context mapping */
97f6c57ea4SArnaud Pouliquen 	res = stm32_rproc_da_to_pa(params[0].value.a, da, size, &pa);
98f6c57ea4SArnaud Pouliquen 	if (res)
99f6c57ea4SArnaud Pouliquen 		return res;
100f6c57ea4SArnaud Pouliquen 
101f6c57ea4SArnaud Pouliquen 	if (stm32_rproc_map(params[0].value.a, pa, size, &dst)) {
102f6c57ea4SArnaud Pouliquen 		EMSG("Can't map region %#"PRIxPA" size %zu", pa, size);
103f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_GENERIC;
104f6c57ea4SArnaud Pouliquen 	}
105f6c57ea4SArnaud Pouliquen 
106f6c57ea4SArnaud Pouliquen 	/* Copy the segment to the remote processor memory */
107f6c57ea4SArnaud Pouliquen 	memcpy(dst, src, size);
108f6c57ea4SArnaud Pouliquen 
109f6c57ea4SArnaud Pouliquen 	/* Verify that loaded segment is valid */
110f6c57ea4SArnaud Pouliquen 	res = hash_sha256_check(hash, dst, size);
111f6c57ea4SArnaud Pouliquen 	if (res)
112f6c57ea4SArnaud Pouliquen 		memset(dst, 0, size);
113f6c57ea4SArnaud Pouliquen 
114f6c57ea4SArnaud Pouliquen 	stm32_rproc_unmap(params[0].value.a, dst, size);
115f6c57ea4SArnaud Pouliquen 
116f6c57ea4SArnaud Pouliquen 	return res;
117f6c57ea4SArnaud Pouliquen }
118f6c57ea4SArnaud Pouliquen 
rproc_pta_set_memory(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])119f6c57ea4SArnaud Pouliquen static TEE_Result rproc_pta_set_memory(uint32_t pt,
120f6c57ea4SArnaud Pouliquen 				       TEE_Param params[TEE_NUM_PARAMS])
121f6c57ea4SArnaud Pouliquen {
122f6c57ea4SArnaud Pouliquen 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
123f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_VALUE_INPUT,
124f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_VALUE_INPUT,
125f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_VALUE_INPUT);
126f6c57ea4SArnaud Pouliquen 	TEE_Result res = TEE_ERROR_GENERIC;
127f6c57ea4SArnaud Pouliquen 	paddr_t pa = 0;
128f6c57ea4SArnaud Pouliquen 	void *dst = NULL;
129f6c57ea4SArnaud Pouliquen 	paddr_t da = params[1].value.a;
130f6c57ea4SArnaud Pouliquen 	size_t size = params[2].value.a;
131f6c57ea4SArnaud Pouliquen 	uint8_t value = params[3].value.a && 0xFF;
132f6c57ea4SArnaud Pouliquen 
133f6c57ea4SArnaud Pouliquen 	if (pt != exp_pt)
134f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_BAD_PARAMETERS;
135f6c57ea4SArnaud Pouliquen 
136f6c57ea4SArnaud Pouliquen 	if (rproc_ta_state != REMOTEPROC_OFF)
137f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_BAD_STATE;
138f6c57ea4SArnaud Pouliquen 
139f6c57ea4SArnaud Pouliquen 	/* Get the physical address in CPU mapping */
140f6c57ea4SArnaud Pouliquen 	res = stm32_rproc_da_to_pa(params[0].value.a, da, size, &pa);
141f6c57ea4SArnaud Pouliquen 	if (res)
142f6c57ea4SArnaud Pouliquen 		return res;
143f6c57ea4SArnaud Pouliquen 
144f6c57ea4SArnaud Pouliquen 	res = stm32_rproc_map(params[0].value.a, pa, size, &dst);
145f6c57ea4SArnaud Pouliquen 	if (res) {
146f6c57ea4SArnaud Pouliquen 		EMSG("Can't map region %#"PRIxPA" size %zu", pa, size);
147f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_GENERIC;
148f6c57ea4SArnaud Pouliquen 	}
149f6c57ea4SArnaud Pouliquen 
150f6c57ea4SArnaud Pouliquen 	memset(dst, value, size);
151f6c57ea4SArnaud Pouliquen 
152f6c57ea4SArnaud Pouliquen 	return stm32_rproc_unmap(params[0].value.a, dst, size);
153f6c57ea4SArnaud Pouliquen }
154f6c57ea4SArnaud Pouliquen 
rproc_pta_da_to_pa(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])155f6c57ea4SArnaud Pouliquen static TEE_Result rproc_pta_da_to_pa(uint32_t pt,
156f6c57ea4SArnaud Pouliquen 				     TEE_Param params[TEE_NUM_PARAMS])
157f6c57ea4SArnaud Pouliquen {
158f6c57ea4SArnaud Pouliquen 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
159f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_VALUE_INPUT,
160f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_VALUE_INPUT,
161f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_VALUE_OUTPUT);
162f6c57ea4SArnaud Pouliquen 	TEE_Result res = TEE_ERROR_GENERIC;
163f6c57ea4SArnaud Pouliquen 	paddr_t da = params[1].value.a;
164f6c57ea4SArnaud Pouliquen 	size_t size = params[2].value.a;
165f6c57ea4SArnaud Pouliquen 	paddr_t pa = 0;
166f6c57ea4SArnaud Pouliquen 
167f6c57ea4SArnaud Pouliquen 	DMSG("Conversion for address %#"PRIxPA" size %zu", da, size);
168f6c57ea4SArnaud Pouliquen 
169f6c57ea4SArnaud Pouliquen 	if (pt != exp_pt)
170f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_BAD_PARAMETERS;
171f6c57ea4SArnaud Pouliquen 
172f6c57ea4SArnaud Pouliquen 	/* Target address is expected 32bit, ensure 32bit MSB are zero */
173f6c57ea4SArnaud Pouliquen 	if (params[1].value.b || params[2].value.b)
174f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_BAD_PARAMETERS;
175f6c57ea4SArnaud Pouliquen 
176f6c57ea4SArnaud Pouliquen 	res = stm32_rproc_da_to_pa(params[0].value.a, da, size, &pa);
177f6c57ea4SArnaud Pouliquen 	if (res)
178f6c57ea4SArnaud Pouliquen 		return res;
179f6c57ea4SArnaud Pouliquen 
180f6c57ea4SArnaud Pouliquen 	reg_pair_from_64((uint64_t)pa, &params[3].value.b, &params[3].value.a);
181f6c57ea4SArnaud Pouliquen 
182f6c57ea4SArnaud Pouliquen 	return TEE_SUCCESS;
183f6c57ea4SArnaud Pouliquen }
184f6c57ea4SArnaud Pouliquen 
rproc_pta_start(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])185f6c57ea4SArnaud Pouliquen static TEE_Result rproc_pta_start(uint32_t pt,
186f6c57ea4SArnaud Pouliquen 				  TEE_Param params[TEE_NUM_PARAMS])
187f6c57ea4SArnaud Pouliquen {
188f6c57ea4SArnaud Pouliquen 	TEE_Result res = TEE_ERROR_GENERIC;
189f6c57ea4SArnaud Pouliquen 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
190f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_NONE,
191f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_NONE,
192f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_NONE);
193f6c57ea4SArnaud Pouliquen 
194f6c57ea4SArnaud Pouliquen 	if (pt != exp_pt)
195f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_BAD_PARAMETERS;
196f6c57ea4SArnaud Pouliquen 
197f6c57ea4SArnaud Pouliquen 	if (rproc_ta_state != REMOTEPROC_OFF)
198f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_BAD_STATE;
199f6c57ea4SArnaud Pouliquen 
200f6c57ea4SArnaud Pouliquen 	res = stm32_rproc_start(params[0].value.a);
201f6c57ea4SArnaud Pouliquen 	if (res)
202f6c57ea4SArnaud Pouliquen 		return res;
203f6c57ea4SArnaud Pouliquen 
204f6c57ea4SArnaud Pouliquen 	rproc_ta_state = REMOTEPROC_ON;
205f6c57ea4SArnaud Pouliquen 
206f6c57ea4SArnaud Pouliquen 	return TEE_SUCCESS;
207f6c57ea4SArnaud Pouliquen }
208f6c57ea4SArnaud Pouliquen 
rproc_pta_stop(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])209f6c57ea4SArnaud Pouliquen static TEE_Result rproc_pta_stop(uint32_t pt,
210f6c57ea4SArnaud Pouliquen 				 TEE_Param params[TEE_NUM_PARAMS])
211f6c57ea4SArnaud Pouliquen {
212f6c57ea4SArnaud Pouliquen 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
213f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_NONE,
214f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_NONE,
215f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_NONE);
216f6c57ea4SArnaud Pouliquen 	TEE_Result res = TEE_ERROR_GENERIC;
217f6c57ea4SArnaud Pouliquen 
218f6c57ea4SArnaud Pouliquen 	if (pt != exp_pt)
219f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_BAD_PARAMETERS;
220f6c57ea4SArnaud Pouliquen 
221f6c57ea4SArnaud Pouliquen 	if (rproc_ta_state != REMOTEPROC_ON)
222f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_BAD_STATE;
223f6c57ea4SArnaud Pouliquen 
224f6c57ea4SArnaud Pouliquen 	res = stm32_rproc_stop(params[0].value.a);
225f6c57ea4SArnaud Pouliquen 	if (res)
226f6c57ea4SArnaud Pouliquen 		return res;
227f6c57ea4SArnaud Pouliquen 
228f6c57ea4SArnaud Pouliquen 	rproc_ta_state = REMOTEPROC_OFF;
229f6c57ea4SArnaud Pouliquen 
230f6c57ea4SArnaud Pouliquen 	return TEE_SUCCESS;
231f6c57ea4SArnaud Pouliquen }
232f6c57ea4SArnaud Pouliquen 
rproc_pta_verify_rsa_signature(TEE_Param * hash,TEE_Param * sig,uint32_t algo)233f6c57ea4SArnaud Pouliquen static TEE_Result rproc_pta_verify_rsa_signature(TEE_Param *hash,
234f6c57ea4SArnaud Pouliquen 						 TEE_Param *sig, uint32_t algo)
235f6c57ea4SArnaud Pouliquen {
236f6c57ea4SArnaud Pouliquen 	struct rsa_public_key key = { };
237f6c57ea4SArnaud Pouliquen 	TEE_Result res = TEE_ERROR_GENERIC;
238f6c57ea4SArnaud Pouliquen 	uint32_t e = TEE_U32_TO_BIG_ENDIAN(rproc_pub_key_exponent);
239f6c57ea4SArnaud Pouliquen 	size_t hash_size = (size_t)hash->memref.size;
240f6c57ea4SArnaud Pouliquen 	size_t sig_size = (size_t)sig->memref.size;
241f6c57ea4SArnaud Pouliquen 
242f6c57ea4SArnaud Pouliquen 	res = crypto_acipher_alloc_rsa_public_key(&key, sig_size);
243f6c57ea4SArnaud Pouliquen 	if (res)
244f6c57ea4SArnaud Pouliquen 		return res;
245f6c57ea4SArnaud Pouliquen 
246f6c57ea4SArnaud Pouliquen 	res = crypto_bignum_bin2bn((uint8_t *)&e, sizeof(e), key.e);
247f6c57ea4SArnaud Pouliquen 	if (res)
248f6c57ea4SArnaud Pouliquen 		goto out;
249f6c57ea4SArnaud Pouliquen 
250f6c57ea4SArnaud Pouliquen 	res = crypto_bignum_bin2bn(rproc_pub_key_modulus,
251f6c57ea4SArnaud Pouliquen 				   rproc_pub_key_modulus_size, key.n);
252f6c57ea4SArnaud Pouliquen 	if (res)
253f6c57ea4SArnaud Pouliquen 		goto out;
254f6c57ea4SArnaud Pouliquen 
255f6c57ea4SArnaud Pouliquen 	res = crypto_acipher_rsassa_verify(algo, &key, hash_size,
256f6c57ea4SArnaud Pouliquen 					   hash->memref.buffer, hash_size,
257f6c57ea4SArnaud Pouliquen 					   sig->memref.buffer, sig_size);
258f6c57ea4SArnaud Pouliquen 
259f6c57ea4SArnaud Pouliquen out:
260f6c57ea4SArnaud Pouliquen 	crypto_acipher_free_rsa_public_key(&key);
261f6c57ea4SArnaud Pouliquen 
262f6c57ea4SArnaud Pouliquen 	return res;
263f6c57ea4SArnaud Pouliquen }
264f6c57ea4SArnaud Pouliquen 
rproc_pta_verify_digest(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])265f6c57ea4SArnaud Pouliquen static TEE_Result rproc_pta_verify_digest(uint32_t pt,
266f6c57ea4SArnaud Pouliquen 					  TEE_Param params[TEE_NUM_PARAMS])
267f6c57ea4SArnaud Pouliquen {
268f6c57ea4SArnaud Pouliquen 	struct rproc_pta_key_info *keyinfo = NULL;
269f6c57ea4SArnaud Pouliquen 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
270f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_MEMREF_INPUT,
271f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_MEMREF_INPUT,
272f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_MEMREF_INPUT);
273f6c57ea4SArnaud Pouliquen 
274f6c57ea4SArnaud Pouliquen 	if (pt != exp_pt)
275f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_BAD_PARAMETERS;
276f6c57ea4SArnaud Pouliquen 
277f6c57ea4SArnaud Pouliquen 	if (!stm32_rproc_get(params[0].value.a))
278f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_NOT_SUPPORTED;
279f6c57ea4SArnaud Pouliquen 
280f6c57ea4SArnaud Pouliquen 	if (rproc_ta_state != REMOTEPROC_OFF)
281f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_BAD_STATE;
282f6c57ea4SArnaud Pouliquen 
283f6c57ea4SArnaud Pouliquen 	keyinfo = params[1].memref.buffer;
284f6c57ea4SArnaud Pouliquen 
285f6c57ea4SArnaud Pouliquen 	if (!keyinfo ||
286f6c57ea4SArnaud Pouliquen 	    rproc_pta_keyinfo_size(keyinfo) != params[1].memref.size)
287f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_BAD_PARAMETERS;
288f6c57ea4SArnaud Pouliquen 
289f6c57ea4SArnaud Pouliquen 	if (keyinfo->algo != TEE_ALG_RSASSA_PKCS1_V1_5_SHA256)
290f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_NOT_SUPPORTED;
291f6c57ea4SArnaud Pouliquen 
292f6c57ea4SArnaud Pouliquen 	return rproc_pta_verify_rsa_signature(&params[2], &params[3],
293f6c57ea4SArnaud Pouliquen 					      keyinfo->algo);
294f6c57ea4SArnaud Pouliquen }
295f6c57ea4SArnaud Pouliquen 
rproc_pta_release_resources(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])296*3ebb0349SArnaud Pouliquen static TEE_Result rproc_pta_release_resources(uint32_t pt,
297*3ebb0349SArnaud Pouliquen 					      TEE_Param params[TEE_NUM_PARAMS])
298*3ebb0349SArnaud Pouliquen {
299*3ebb0349SArnaud Pouliquen 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
300*3ebb0349SArnaud Pouliquen 						TEE_PARAM_TYPE_NONE,
301*3ebb0349SArnaud Pouliquen 						TEE_PARAM_TYPE_NONE,
302*3ebb0349SArnaud Pouliquen 						TEE_PARAM_TYPE_NONE);
303*3ebb0349SArnaud Pouliquen 
304*3ebb0349SArnaud Pouliquen 	if (pt != exp_pt)
305*3ebb0349SArnaud Pouliquen 		return TEE_ERROR_BAD_PARAMETERS;
306*3ebb0349SArnaud Pouliquen 
307*3ebb0349SArnaud Pouliquen 	if (rproc_ta_state != REMOTEPROC_OFF)
308*3ebb0349SArnaud Pouliquen 		return TEE_ERROR_BAD_STATE;
309*3ebb0349SArnaud Pouliquen 
310*3ebb0349SArnaud Pouliquen 	/* Clean the resources */
311*3ebb0349SArnaud Pouliquen 	return stm32_rproc_clean_up_memories(params[0].value.a);
312*3ebb0349SArnaud Pouliquen }
313*3ebb0349SArnaud Pouliquen 
rproc_pta_invoke_command(void * session __unused,uint32_t cmd_id,uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])314f6c57ea4SArnaud Pouliquen static TEE_Result rproc_pta_invoke_command(void *session __unused,
315f6c57ea4SArnaud Pouliquen 					   uint32_t cmd_id,
316f6c57ea4SArnaud Pouliquen 					   uint32_t param_types,
317f6c57ea4SArnaud Pouliquen 					   TEE_Param params[TEE_NUM_PARAMS])
318f6c57ea4SArnaud Pouliquen {
319f6c57ea4SArnaud Pouliquen 	switch (cmd_id) {
320f6c57ea4SArnaud Pouliquen 	case PTA_RPROC_HW_CAPABILITIES:
321f6c57ea4SArnaud Pouliquen 		return rproc_pta_capabilities(param_types, params);
322f6c57ea4SArnaud Pouliquen 	case PTA_RPROC_LOAD_SEGMENT_SHA256:
323f6c57ea4SArnaud Pouliquen 		return rproc_pta_load_segment(param_types, params);
324f6c57ea4SArnaud Pouliquen 	case PTA_RPROC_SET_MEMORY:
325f6c57ea4SArnaud Pouliquen 		return rproc_pta_set_memory(param_types, params);
326f6c57ea4SArnaud Pouliquen 	case PTA_RPROC_FIRMWARE_START:
327f6c57ea4SArnaud Pouliquen 		return rproc_pta_start(param_types, params);
328f6c57ea4SArnaud Pouliquen 	case PTA_RPROC_FIRMWARE_STOP:
329f6c57ea4SArnaud Pouliquen 		return rproc_pta_stop(param_types, params);
330f6c57ea4SArnaud Pouliquen 	case PTA_RPROC_FIRMWARE_DA_TO_PA:
331f6c57ea4SArnaud Pouliquen 		return rproc_pta_da_to_pa(param_types, params);
332f6c57ea4SArnaud Pouliquen 	case PTA_RPROC_VERIFY_DIGEST:
333f6c57ea4SArnaud Pouliquen 		return rproc_pta_verify_digest(param_types, params);
334*3ebb0349SArnaud Pouliquen 	case PTA_REMOTEPROC_RELEASE:
335*3ebb0349SArnaud Pouliquen 		return rproc_pta_release_resources(param_types, params);
336f6c57ea4SArnaud Pouliquen 	default:
337f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_NOT_IMPLEMENTED;
338f6c57ea4SArnaud Pouliquen 	}
339f6c57ea4SArnaud Pouliquen }
340f6c57ea4SArnaud Pouliquen 
341f6c57ea4SArnaud Pouliquen /*
342f6c57ea4SArnaud Pouliquen  * Pseudo Trusted Application entry points
343f6c57ea4SArnaud Pouliquen  */
rproc_pta_open_session(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS],void ** sess_ctx __unused)344f6c57ea4SArnaud Pouliquen static TEE_Result rproc_pta_open_session(uint32_t pt,
345f6c57ea4SArnaud Pouliquen 					 TEE_Param params[TEE_NUM_PARAMS],
346f6c57ea4SArnaud Pouliquen 					 void **sess_ctx __unused)
347f6c57ea4SArnaud Pouliquen {
348f6c57ea4SArnaud Pouliquen 	struct ts_session *s = ts_get_calling_session();
349f6c57ea4SArnaud Pouliquen 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
350f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_NONE,
351f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_NONE,
352f6c57ea4SArnaud Pouliquen 						TEE_PARAM_TYPE_NONE);
353f6c57ea4SArnaud Pouliquen 	struct ts_ctx *ctx = NULL;
354f6c57ea4SArnaud Pouliquen 	TEE_UUID ta_uuid = TA_REMOTEPROC_UUID;
355f6c57ea4SArnaud Pouliquen 
356f6c57ea4SArnaud Pouliquen 	if (pt != exp_pt)
357f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_BAD_PARAMETERS;
358f6c57ea4SArnaud Pouliquen 
359f6c57ea4SArnaud Pouliquen 	if (!s || !is_user_ta_ctx(s->ctx))
360f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_ACCESS_DENIED;
361f6c57ea4SArnaud Pouliquen 
362f6c57ea4SArnaud Pouliquen 	/* Check that we're called by the remoteproc Trusted application*/
363f6c57ea4SArnaud Pouliquen 	ctx = s->ctx;
364f6c57ea4SArnaud Pouliquen 	if (memcmp(&ctx->uuid, &ta_uuid, sizeof(TEE_UUID)))
365f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_ACCESS_DENIED;
366f6c57ea4SArnaud Pouliquen 
367f6c57ea4SArnaud Pouliquen 	if (!stm32_rproc_get(params[0].value.a))
368f6c57ea4SArnaud Pouliquen 		return TEE_ERROR_NOT_SUPPORTED;
369f6c57ea4SArnaud Pouliquen 
370f6c57ea4SArnaud Pouliquen 	return TEE_SUCCESS;
371f6c57ea4SArnaud Pouliquen }
372f6c57ea4SArnaud Pouliquen 
373f6c57ea4SArnaud Pouliquen pseudo_ta_register(.uuid = PTA_RPROC_UUID, .name = PTA_NAME,
374f6c57ea4SArnaud Pouliquen 		   .flags = PTA_DEFAULT_FLAGS,
375f6c57ea4SArnaud Pouliquen 		   .invoke_command_entry_point = rproc_pta_invoke_command,
376f6c57ea4SArnaud Pouliquen 		   .open_session_entry_point = rproc_pta_open_session);
377