172a78b76af1a6e15ef65c8ba45e63ccb85ae9c0
[openwrt/staging/xback.git] /
1 From 6a0bc3522e746025e2d9a63ab2cb5d7062c2d39c Mon Sep 17 00:00:00 2001
2 From: Patrick Delaunay <patrick.delaunay@foss.st.com>
3 Date: Mon, 6 Feb 2023 13:43:51 +0000
4 Subject: [PATCH] nvmem: stm32: add OP-TEE support for STM32MP13x
5
6 For boot with OP-TEE on STM32MP13, the communication with the secure
7 world no more use STMicroelectronics SMC but communication with the
8 STM32MP BSEC TA, for data access (read/write) or lock operation:
9 - all the request are sent to OP-TEE trusted application,
10 - for upper OTP with ECC protection and with word programming only
11 each OTP are permanently locked when programmed to avoid ECC error
12 on the second write operation
13
14 Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
15 Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
16 Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
17 Link: https://lore.kernel.org/r/20230206134356.839737-18-srinivas.kandagatla@linaro.org
18 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
19 ---
20 drivers/nvmem/Kconfig | 11 +
21 drivers/nvmem/Makefile | 1 +
22 drivers/nvmem/stm32-bsec-optee-ta.c | 298 ++++++++++++++++++++++++++++
23 drivers/nvmem/stm32-bsec-optee-ta.h | 80 ++++++++
24 drivers/nvmem/stm32-romem.c | 54 ++++-
25 5 files changed, 441 insertions(+), 3 deletions(-)
26 create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.c
27 create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.h
28
29 --- a/drivers/nvmem/Kconfig
30 +++ b/drivers/nvmem/Kconfig
31 @@ -290,9 +290,20 @@ config NVMEM_SPRD_EFUSE
32 This driver can also be built as a module. If so, the module
33 will be called nvmem-sprd-efuse.
34
35 +config NVMEM_STM32_BSEC_OPTEE_TA
36 + bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver"
37 + depends on OPTEE
38 + help
39 + Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE
40 + trusted application STM32MP BSEC.
41 +
42 + This library is a used by stm32-romem driver or included in the module
43 + called nvmem-stm32-romem.
44 +
45 config NVMEM_STM32_ROMEM
46 tristate "STMicroelectronics STM32 factory-programmed memory support"
47 depends on ARCH_STM32 || COMPILE_TEST
48 + imply NVMEM_STM32_BSEC_OPTEE_TA
49 help
50 Say y here to enable read-only access for STMicroelectronics STM32
51 factory-programmed memory area.
52 --- a/drivers/nvmem/Makefile
53 +++ b/drivers/nvmem/Makefile
54 @@ -61,6 +61,7 @@ obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem
55 nvmem_sprd_efuse-y := sprd-efuse.o
56 obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o
57 nvmem_stm32_romem-y := stm32-romem.o
58 +nvmem_stm32_romem-$(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA) += stm32-bsec-optee-ta.o
59 obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvmem_sunplus_ocotp.o
60 nvmem_sunplus_ocotp-y := sunplus-ocotp.o
61 obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o
62 --- /dev/null
63 +++ b/drivers/nvmem/stm32-bsec-optee-ta.c
64 @@ -0,0 +1,298 @@
65 +// SPDX-License-Identifier: GPL-2.0-or-later
66 +/*
67 + * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver
68 + *
69 + * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
70 + */
71 +
72 +#include <linux/tee_drv.h>
73 +
74 +#include "stm32-bsec-optee-ta.h"
75 +
76 +/*
77 + * Read OTP memory
78 + *
79 + * [in] value[0].a OTP start offset in byte
80 + * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock)
81 + * [out] memref[1].buffer Output buffer to store read values
82 + * [out] memref[1].size Size of OTP to be read
83 + *
84 + * Return codes:
85 + * TEE_SUCCESS - Invoke command success
86 + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
87 + * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller
88 + */
89 +#define PTA_BSEC_READ_MEM 0x0
90 +
91 +/*
92 + * Write OTP memory
93 + *
94 + * [in] value[0].a OTP start offset in byte
95 + * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock)
96 + * [in] memref[1].buffer Input buffer to read values
97 + * [in] memref[1].size Size of OTP to be written
98 + *
99 + * Return codes:
100 + * TEE_SUCCESS - Invoke command success
101 + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
102 + * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller
103 + */
104 +#define PTA_BSEC_WRITE_MEM 0x1
105 +
106 +/* value of PTA_BSEC access type = value[in] b */
107 +#define SHADOW_ACCESS 0
108 +#define FUSE_ACCESS 1
109 +#define LOCK_ACCESS 2
110 +
111 +/* Bitfield definition for LOCK status */
112 +#define LOCK_PERM BIT(30)
113 +
114 +/* OP-TEE STM32MP BSEC TA UUID */
115 +static const uuid_t stm32mp_bsec_ta_uuid =
116 + UUID_INIT(0x94cf71ad, 0x80e6, 0x40b5,
117 + 0xa7, 0xc6, 0x3d, 0xc5, 0x01, 0xeb, 0x28, 0x03);
118 +
119 +/*
120 + * Check whether this driver supports the BSEC TA in the TEE instance
121 + * represented by the params (ver/data) to this function.
122 + */
123 +static int stm32_bsec_optee_ta_match(struct tee_ioctl_version_data *ver,
124 + const void *data)
125 +{
126 + /* Currently this driver only supports GP compliant, OP-TEE based TA */
127 + if ((ver->impl_id == TEE_IMPL_ID_OPTEE) &&
128 + (ver->gen_caps & TEE_GEN_CAP_GP))
129 + return 1;
130 + else
131 + return 0;
132 +}
133 +
134 +/* Open a session to OP-TEE for STM32MP BSEC TA */
135 +static int stm32_bsec_ta_open_session(struct tee_context *ctx, u32 *id)
136 +{
137 + struct tee_ioctl_open_session_arg sess_arg;
138 + int rc;
139 +
140 + memset(&sess_arg, 0, sizeof(sess_arg));
141 + export_uuid(sess_arg.uuid, &stm32mp_bsec_ta_uuid);
142 + sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
143 + sess_arg.num_params = 0;
144 +
145 + rc = tee_client_open_session(ctx, &sess_arg, NULL);
146 + if ((rc < 0) || (sess_arg.ret != 0)) {
147 + pr_err("%s: tee_client_open_session failed err:%#x, ret:%#x\n",
148 + __func__, sess_arg.ret, rc);
149 + if (!rc)
150 + rc = -EINVAL;
151 + } else {
152 + *id = sess_arg.session;
153 + }
154 +
155 + return rc;
156 +}
157 +
158 +/* close a session to OP-TEE for STM32MP BSEC TA */
159 +static void stm32_bsec_ta_close_session(void *ctx, u32 id)
160 +{
161 + tee_client_close_session(ctx, id);
162 +}
163 +
164 +/* stm32_bsec_optee_ta_open() - initialize the STM32MP BSEC TA */
165 +int stm32_bsec_optee_ta_open(struct tee_context **ctx)
166 +{
167 + struct tee_context *tee_ctx;
168 + u32 session_id;
169 + int rc;
170 +
171 + /* Open context with TEE driver */
172 + tee_ctx = tee_client_open_context(NULL, stm32_bsec_optee_ta_match, NULL, NULL);
173 + if (IS_ERR(tee_ctx)) {
174 + rc = PTR_ERR(tee_ctx);
175 + if (rc == -ENOENT)
176 + return -EPROBE_DEFER;
177 + pr_err("%s: tee_client_open_context failed (%d)\n", __func__, rc);
178 +
179 + return rc;
180 + }
181 +
182 + /* Check STM32MP BSEC TA presence */
183 + rc = stm32_bsec_ta_open_session(tee_ctx, &session_id);
184 + if (rc) {
185 + tee_client_close_context(tee_ctx);
186 + return rc;
187 + }
188 +
189 + stm32_bsec_ta_close_session(tee_ctx, session_id);
190 +
191 + *ctx = tee_ctx;
192 +
193 + return 0;
194 +}
195 +
196 +/* stm32_bsec_optee_ta_open() - release the PTA STM32MP BSEC TA */
197 +void stm32_bsec_optee_ta_close(void *ctx)
198 +{
199 + tee_client_close_context(ctx);
200 +}
201 +
202 +/* stm32_bsec_optee_ta_read() - nvmem read access using PTA client driver */
203 +int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
204 + void *buf, size_t bytes)
205 +{
206 + struct tee_shm *shm;
207 + struct tee_ioctl_invoke_arg arg;
208 + struct tee_param param[2];
209 + u8 *shm_buf;
210 + u32 start, num_bytes;
211 + int ret;
212 + u32 session_id;
213 +
214 + ret = stm32_bsec_ta_open_session(ctx, &session_id);
215 + if (ret)
216 + return ret;
217 +
218 + memset(&arg, 0, sizeof(arg));
219 + memset(&param, 0, sizeof(param));
220 +
221 + arg.func = PTA_BSEC_READ_MEM;
222 + arg.session = session_id;
223 + arg.num_params = 2;
224 +
225 + /* align access on 32bits */
226 + start = ALIGN_DOWN(offset, 4);
227 + num_bytes = round_up(offset + bytes - start, 4);
228 + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
229 + param[0].u.value.a = start;
230 + param[0].u.value.b = SHADOW_ACCESS;
231 +
232 + shm = tee_shm_alloc_kernel_buf(ctx, num_bytes);
233 + if (IS_ERR(shm)) {
234 + ret = PTR_ERR(shm);
235 + goto out_tee_session;
236 + }
237 +
238 + param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
239 + param[1].u.memref.shm = shm;
240 + param[1].u.memref.size = num_bytes;
241 +
242 + ret = tee_client_invoke_func(ctx, &arg, param);
243 + if (ret < 0 || arg.ret != 0) {
244 + pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n",
245 + arg.ret, ret);
246 + if (!ret)
247 + ret = -EIO;
248 + }
249 + if (!ret) {
250 + shm_buf = tee_shm_get_va(shm, 0);
251 + if (IS_ERR(shm_buf)) {
252 + ret = PTR_ERR(shm_buf);
253 + pr_err("tee_shm_get_va failed for transmit (%d)\n", ret);
254 + } else {
255 + /* read data from 32 bits aligned buffer */
256 + memcpy(buf, &shm_buf[offset % 4], bytes);
257 + }
258 + }
259 +
260 + tee_shm_free(shm);
261 +
262 +out_tee_session:
263 + stm32_bsec_ta_close_session(ctx, session_id);
264 +
265 + return ret;
266 +}
267 +
268 +/* stm32_bsec_optee_ta_write() - nvmem write access using PTA client driver */
269 +int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
270 + unsigned int offset, void *buf, size_t bytes)
271 +{ struct tee_shm *shm;
272 + struct tee_ioctl_invoke_arg arg;
273 + struct tee_param param[2];
274 + u8 *shm_buf;
275 + int ret;
276 + u32 session_id;
277 +
278 + ret = stm32_bsec_ta_open_session(ctx, &session_id);
279 + if (ret)
280 + return ret;
281 +
282 + /* Allow only writing complete 32-bits aligned words */
283 + if ((bytes % 4) || (offset % 4))
284 + return -EINVAL;
285 +
286 + memset(&arg, 0, sizeof(arg));
287 + memset(&param, 0, sizeof(param));
288 +
289 + arg.func = PTA_BSEC_WRITE_MEM;
290 + arg.session = session_id;
291 + arg.num_params = 2;
292 +
293 + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
294 + param[0].u.value.a = offset;
295 + param[0].u.value.b = FUSE_ACCESS;
296 +
297 + shm = tee_shm_alloc_kernel_buf(ctx, bytes);
298 + if (IS_ERR(shm)) {
299 + ret = PTR_ERR(shm);
300 + goto out_tee_session;
301 + }
302 +
303 + param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
304 + param[1].u.memref.shm = shm;
305 + param[1].u.memref.size = bytes;
306 +
307 + shm_buf = tee_shm_get_va(shm, 0);
308 + if (IS_ERR(shm_buf)) {
309 + ret = PTR_ERR(shm_buf);
310 + pr_err("tee_shm_get_va failed for transmit (%d)\n", ret);
311 + tee_shm_free(shm);
312 +
313 + goto out_tee_session;
314 + }
315 +
316 + memcpy(shm_buf, buf, bytes);
317 +
318 + ret = tee_client_invoke_func(ctx, &arg, param);
319 + if (ret < 0 || arg.ret != 0) {
320 + pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret);
321 + if (!ret)
322 + ret = -EIO;
323 + }
324 + pr_debug("Write OTPs %d to %zu, ret=%d\n", offset / 4, (offset + bytes) / 4, ret);
325 +
326 + /* Lock the upper OTPs with ECC protection, word programming only */
327 + if (!ret && ((offset + bytes) >= (lower * 4))) {
328 + u32 start, nb_lock;
329 + u32 *lock = (u32 *)shm_buf;
330 + int i;
331 +
332 + /*
333 + * don't lock the lower OTPs, no ECC protection and incremental
334 + * bit programming, a second write is allowed
335 + */
336 + start = max_t(u32, offset, lower * 4);
337 + nb_lock = (offset + bytes - start) / 4;
338 +
339 + param[0].u.value.a = start;
340 + param[0].u.value.b = LOCK_ACCESS;
341 + param[1].u.memref.size = nb_lock * 4;
342 +
343 + for (i = 0; i < nb_lock; i++)
344 + lock[i] = LOCK_PERM;
345 +
346 + ret = tee_client_invoke_func(ctx, &arg, param);
347 + if (ret < 0 || arg.ret != 0) {
348 + pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret);
349 + if (!ret)
350 + ret = -EIO;
351 + }
352 + pr_debug("Lock upper OTPs %d to %d, ret=%d\n",
353 + start / 4, start / 4 + nb_lock, ret);
354 + }
355 +
356 + tee_shm_free(shm);
357 +
358 +out_tee_session:
359 + stm32_bsec_ta_close_session(ctx, session_id);
360 +
361 + return ret;
362 +}
363 --- /dev/null
364 +++ b/drivers/nvmem/stm32-bsec-optee-ta.h
365 @@ -0,0 +1,80 @@
366 +/* SPDX-License-Identifier: GPL-2.0-or-later */
367 +/*
368 + * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver
369 + *
370 + * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
371 + */
372 +
373 +#if IS_ENABLED(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA)
374 +/**
375 + * stm32_bsec_optee_ta_open() - initialize the STM32 BSEC TA
376 + * @ctx: the OP-TEE context on success
377 + *
378 + * Return:
379 + * On success, 0. On failure, -errno.
380 + */
381 +int stm32_bsec_optee_ta_open(struct tee_context **ctx);
382 +
383 +/**
384 + * stm32_bsec_optee_ta_close() - release the STM32 BSEC TA
385 + * @ctx: the OP-TEE context
386 + *
387 + * This function used to clean the OP-TEE resources initialized in
388 + * stm32_bsec_optee_ta_open(); it can be used as callback to
389 + * devm_add_action_or_reset()
390 + */
391 +void stm32_bsec_optee_ta_close(void *ctx);
392 +
393 +/**
394 + * stm32_bsec_optee_ta_read() - nvmem read access using TA client driver
395 + * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open
396 + * @offset: nvmem offset
397 + * @buf: buffer to fill with nvem values
398 + * @bytes: number of bytes to read
399 + *
400 + * Return:
401 + * On success, 0. On failure, -errno.
402 + */
403 +int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
404 + void *buf, size_t bytes);
405 +
406 +/**
407 + * stm32_bsec_optee_ta_write() - nvmem write access using TA client driver
408 + * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open
409 + * @lower: number of lower OTP, not protected by ECC
410 + * @offset: nvmem offset
411 + * @buf: buffer with nvem values
412 + * @bytes: number of bytes to write
413 + *
414 + * Return:
415 + * On success, 0. On failure, -errno.
416 + */
417 +int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
418 + unsigned int offset, void *buf, size_t bytes);
419 +
420 +#else
421 +
422 +static inline int stm32_bsec_optee_ta_open(struct tee_context **ctx)
423 +{
424 + return -EOPNOTSUPP;
425 +}
426 +
427 +static inline void stm32_bsec_optee_ta_close(void *ctx)
428 +{
429 +}
430 +
431 +static inline int stm32_bsec_optee_ta_read(struct tee_context *ctx,
432 + unsigned int offset, void *buf,
433 + size_t bytes)
434 +{
435 + return -EOPNOTSUPP;
436 +}
437 +
438 +static inline int stm32_bsec_optee_ta_write(struct tee_context *ctx,
439 + unsigned int lower,
440 + unsigned int offset, void *buf,
441 + size_t bytes)
442 +{
443 + return -EOPNOTSUPP;
444 +}
445 +#endif /* CONFIG_NVMEM_STM32_BSEC_OPTEE_TA */
446 --- a/drivers/nvmem/stm32-romem.c
447 +++ b/drivers/nvmem/stm32-romem.c
448 @@ -11,6 +11,9 @@
449 #include <linux/module.h>
450 #include <linux/nvmem-provider.h>
451 #include <linux/of_device.h>
452 +#include <linux/tee_drv.h>
453 +
454 +#include "stm32-bsec-optee-ta.h"
455
456 /* BSEC secure service access from non-secure */
457 #define STM32_SMC_BSEC 0x82001003
458 @@ -25,12 +28,14 @@
459 struct stm32_romem_cfg {
460 int size;
461 u8 lower;
462 + bool ta;
463 };
464
465 struct stm32_romem_priv {
466 void __iomem *base;
467 struct nvmem_config cfg;
468 u8 lower;
469 + struct tee_context *ctx;
470 };
471
472 static int stm32_romem_read(void *context, unsigned int offset, void *buf,
473 @@ -138,12 +143,29 @@ static int stm32_bsec_write(void *contex
474 return 0;
475 }
476
477 +static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf,
478 + size_t bytes)
479 +{
480 + struct stm32_romem_priv *priv = context;
481 +
482 + return stm32_bsec_optee_ta_read(priv->ctx, offset, buf, bytes);
483 +}
484 +
485 +static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf,
486 + size_t bytes)
487 +{
488 + struct stm32_romem_priv *priv = context;
489 +
490 + return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes);
491 +}
492 +
493 static int stm32_romem_probe(struct platform_device *pdev)
494 {
495 const struct stm32_romem_cfg *cfg;
496 struct device *dev = &pdev->dev;
497 struct stm32_romem_priv *priv;
498 struct resource *res;
499 + int rc;
500
501 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
502 if (!priv)
503 @@ -173,15 +195,31 @@ static int stm32_romem_probe(struct plat
504 } else {
505 priv->cfg.size = cfg->size;
506 priv->lower = cfg->lower;
507 - priv->cfg.reg_read = stm32_bsec_read;
508 - priv->cfg.reg_write = stm32_bsec_write;
509 + if (cfg->ta) {
510 + rc = stm32_bsec_optee_ta_open(&priv->ctx);
511 + /* wait for OP-TEE client driver to be up and ready */
512 + if (rc)
513 + return rc;
514 + }
515 + if (priv->ctx) {
516 + rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx);
517 + if (rc) {
518 + dev_err(dev, "devm_add_action_or_reset() failed (%d)\n", rc);
519 + return rc;
520 + }
521 + priv->cfg.reg_read = stm32_bsec_pta_read;
522 + priv->cfg.reg_write = stm32_bsec_pta_write;
523 + } else {
524 + priv->cfg.reg_read = stm32_bsec_read;
525 + priv->cfg.reg_write = stm32_bsec_write;
526 + }
527 }
528
529 return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg));
530 }
531
532 /*
533 - * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits)
534 + * STM32MP15/13 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits)
535 * => 96 x 32-bits data words
536 * - Lower: 1K bits, 2:1 redundancy, incremental bit programming
537 * => 32 (x 32-bits) lower shadow registers = words 0 to 31
538 @@ -191,6 +229,13 @@ static int stm32_romem_probe(struct plat
539 static const struct stm32_romem_cfg stm32mp15_bsec_cfg = {
540 .size = 384,
541 .lower = 32,
542 + .ta = false,
543 +};
544 +
545 +static const struct stm32_romem_cfg stm32mp13_bsec_cfg = {
546 + .size = 384,
547 + .lower = 32,
548 + .ta = true,
549 };
550
551 static const struct of_device_id stm32_romem_of_match[] = {
552 @@ -198,7 +243,10 @@ static const struct of_device_id stm32_r
553 .compatible = "st,stm32mp15-bsec",
554 .data = (void *)&stm32mp15_bsec_cfg,
555 }, {
556 + .compatible = "st,stm32mp13-bsec",
557 + .data = (void *)&stm32mp13_bsec_cfg,
558 },
559 + { /* sentinel */ },
560 };
561 MODULE_DEVICE_TABLE(of, stm32_romem_of_match);
562