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