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, ¶ms[3].value.b, ¶ms[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(¶ms[2], ¶ms[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