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
rproc_pta_capabilities(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])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
rproc_pta_load_segment(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])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
rproc_pta_set_memory(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])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
rproc_pta_da_to_pa(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])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, ¶ms[3].value.b, ¶ms[3].value.a);
181
182 return TEE_SUCCESS;
183 }
184
rproc_pta_start(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])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
rproc_pta_stop(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])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
rproc_pta_verify_rsa_signature(TEE_Param * hash,TEE_Param * sig,uint32_t algo)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
rproc_pta_verify_digest(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])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(¶ms[2], ¶ms[3],
293 keyinfo->algo);
294 }
295
rproc_pta_release_resources(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])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
rproc_pta_invoke_command(void * session __unused,uint32_t cmd_id,uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])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 */
rproc_pta_open_session(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS],void ** sess_ctx __unused)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