xref: /optee_os/core/pta/stm32mp/remoteproc_pta.c (revision cb03400251f98aed22a2664509e3ed9e183800b0)
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_release_resources(uint32_t pt,
297 					      TEE_Param params[TEE_NUM_PARAMS])
298 {
299 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
300 						TEE_PARAM_TYPE_NONE,
301 						TEE_PARAM_TYPE_NONE,
302 						TEE_PARAM_TYPE_NONE);
303 
304 	if (pt != exp_pt)
305 		return TEE_ERROR_BAD_PARAMETERS;
306 
307 	if (rproc_ta_state != REMOTEPROC_OFF)
308 		return TEE_ERROR_BAD_STATE;
309 
310 	/* Clean the resources */
311 	return stm32_rproc_clean_up_memories(params[0].value.a);
312 }
313 
314 static TEE_Result rproc_pta_invoke_command(void *session __unused,
315 					   uint32_t cmd_id,
316 					   uint32_t param_types,
317 					   TEE_Param params[TEE_NUM_PARAMS])
318 {
319 	switch (cmd_id) {
320 	case PTA_RPROC_HW_CAPABILITIES:
321 		return rproc_pta_capabilities(param_types, params);
322 	case PTA_RPROC_LOAD_SEGMENT_SHA256:
323 		return rproc_pta_load_segment(param_types, params);
324 	case PTA_RPROC_SET_MEMORY:
325 		return rproc_pta_set_memory(param_types, params);
326 	case PTA_RPROC_FIRMWARE_START:
327 		return rproc_pta_start(param_types, params);
328 	case PTA_RPROC_FIRMWARE_STOP:
329 		return rproc_pta_stop(param_types, params);
330 	case PTA_RPROC_FIRMWARE_DA_TO_PA:
331 		return rproc_pta_da_to_pa(param_types, params);
332 	case PTA_RPROC_VERIFY_DIGEST:
333 		return rproc_pta_verify_digest(param_types, params);
334 	case PTA_REMOTEPROC_RELEASE:
335 		return rproc_pta_release_resources(param_types, params);
336 	default:
337 		return TEE_ERROR_NOT_IMPLEMENTED;
338 	}
339 }
340 
341 /*
342  * Pseudo Trusted Application entry points
343  */
344 static TEE_Result rproc_pta_open_session(uint32_t pt,
345 					 TEE_Param params[TEE_NUM_PARAMS],
346 					 void **sess_ctx __unused)
347 {
348 	struct ts_session *s = ts_get_calling_session();
349 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
350 						TEE_PARAM_TYPE_NONE,
351 						TEE_PARAM_TYPE_NONE,
352 						TEE_PARAM_TYPE_NONE);
353 	struct ts_ctx *ctx = NULL;
354 	TEE_UUID ta_uuid = TA_REMOTEPROC_UUID;
355 
356 	if (pt != exp_pt)
357 		return TEE_ERROR_BAD_PARAMETERS;
358 
359 	if (!s || !is_user_ta_ctx(s->ctx))
360 		return TEE_ERROR_ACCESS_DENIED;
361 
362 	/* Check that we're called by the remoteproc Trusted application*/
363 	ctx = s->ctx;
364 	if (memcmp(&ctx->uuid, &ta_uuid, sizeof(TEE_UUID)))
365 		return TEE_ERROR_ACCESS_DENIED;
366 
367 	if (!stm32_rproc_get(params[0].value.a))
368 		return TEE_ERROR_NOT_SUPPORTED;
369 
370 	return TEE_SUCCESS;
371 }
372 
373 pseudo_ta_register(.uuid = PTA_RPROC_UUID, .name = PTA_NAME,
374 		   .flags = PTA_DEFAULT_FLAGS,
375 		   .invoke_command_entry_point = rproc_pta_invoke_command,
376 		   .open_session_entry_point = rproc_pta_open_session);
377