Merge tag 'v2021.04-rc4' into next
[platform/kernel/u-boot.git] / drivers / tee / sandbox.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2018 Linaro Limited
4  */
5 #include <common.h>
6 #include <dm.h>
7 #include <sandboxtee.h>
8 #include <tee.h>
9 #include <tee/optee_ta_avb.h>
10 #include <tee/optee_ta_rpc_test.h>
11 #include <tee/optee_ta_scp03.h>
12
13 #include "optee/optee_msg.h"
14 #include "optee/optee_private.h"
15
16 /*
17  * The sandbox tee driver tries to emulate a generic Trusted Exectution
18  * Environment (TEE) with the Trusted Applications (TA) OPTEE_TA_AVB and
19  * OPTEE_TA_RPC_TEST available.
20  */
21
22 static const u32 pstorage_max = 16;
23 /**
24  * struct ta_entry - TA entries
25  * @uuid:               UUID of an emulated TA
26  * @open_session        Called when a session is openened to the TA
27  * @invoke_func         Called when a function in the TA is to be invoked
28  *
29  * This struct is used to register TAs in this sandbox emulation of a TEE.
30  */
31 struct ta_entry {
32         struct tee_optee_ta_uuid uuid;
33         u32 (*open_session)(struct udevice *dev, uint num_params,
34                             struct tee_param *params);
35         u32 (*invoke_func)(struct udevice *dev,
36                            u32 func, uint num_params,
37                            struct tee_param *params);
38 };
39
40 static int get_msg_arg(struct udevice *dev, uint num_params,
41                        struct tee_shm **shmp, struct optee_msg_arg **msg_arg)
42 {
43         int rc;
44         struct optee_msg_arg *ma;
45
46         rc = __tee_shm_add(dev, OPTEE_MSG_NONCONTIG_PAGE_SIZE, NULL,
47                            OPTEE_MSG_GET_ARG_SIZE(num_params), TEE_SHM_ALLOC,
48                            shmp);
49         if (rc)
50                 return rc;
51
52         ma = (*shmp)->addr;
53         memset(ma, 0, OPTEE_MSG_GET_ARG_SIZE(num_params));
54         ma->num_params = num_params;
55         *msg_arg = ma;
56
57         return 0;
58 }
59
60 void *optee_alloc_and_init_page_list(void *buf, ulong len,
61                                      u64 *phys_buf_ptr)
62 {
63         /*
64          * An empty stub is added just to fix linking issues.
65          * This function isn't supposed to be called in sandbox
66          * setup, otherwise replace this with a proper
67          * implementation from optee/core.c
68          */
69         return NULL;
70 }
71
72 #if defined(CONFIG_OPTEE_TA_SCP03) || defined(CONFIG_OPTEE_TA_AVB)
73 static u32 get_attr(uint n, uint num_params, struct tee_param *params)
74 {
75         if (n >= num_params)
76                 return TEE_PARAM_ATTR_TYPE_NONE;
77
78         return params[n].attr;
79 }
80
81 static u32 check_params(u8 p0, u8 p1, u8 p2, u8 p3, uint num_params,
82                         struct tee_param *params)
83 {
84         u8 p[] = { p0, p1, p2, p3 };
85         uint n;
86
87         for (n = 0; n < ARRAY_SIZE(p); n++)
88                 if (p[n] != get_attr(n, num_params, params))
89                         goto bad_params;
90
91         for (; n < num_params; n++)
92                 if (get_attr(n, num_params, params))
93                         goto bad_params;
94
95         return TEE_SUCCESS;
96
97 bad_params:
98         printf("Bad param attrs\n");
99
100         return TEE_ERROR_BAD_PARAMETERS;
101 }
102 #endif
103
104 #ifdef CONFIG_OPTEE_TA_SCP03
105 static u32 pta_scp03_open_session(struct udevice *dev, uint num_params,
106                                   struct tee_param *params)
107 {
108         /*
109          * We don't expect additional parameters when opening a session to
110          * this TA.
111          */
112         return check_params(TEE_PARAM_ATTR_TYPE_NONE, TEE_PARAM_ATTR_TYPE_NONE,
113                             TEE_PARAM_ATTR_TYPE_NONE, TEE_PARAM_ATTR_TYPE_NONE,
114                             num_params, params);
115 }
116
117 static u32 pta_scp03_invoke_func(struct udevice *dev, u32 func, uint num_params,
118                                  struct tee_param *params)
119 {
120         u32 res;
121         static bool enabled;
122
123         switch (func) {
124         case PTA_CMD_ENABLE_SCP03:
125                 res = check_params(TEE_PARAM_ATTR_TYPE_VALUE_INPUT,
126                                    TEE_PARAM_ATTR_TYPE_NONE,
127                                    TEE_PARAM_ATTR_TYPE_NONE,
128                                    TEE_PARAM_ATTR_TYPE_NONE,
129                                    num_params, params);
130                 if (res)
131                         return res;
132
133                 if (!enabled) {
134                         enabled = true;
135                 } else {
136                 }
137
138                 if (params[0].u.value.a)
139
140                 return TEE_SUCCESS;
141         default:
142                 return TEE_ERROR_NOT_SUPPORTED;
143         }
144 }
145 #endif
146
147 #ifdef CONFIG_OPTEE_TA_AVB
148 static u32 ta_avb_open_session(struct udevice *dev, uint num_params,
149                                struct tee_param *params)
150 {
151         /*
152          * We don't expect additional parameters when opening a session to
153          * this TA.
154          */
155         return check_params(TEE_PARAM_ATTR_TYPE_NONE, TEE_PARAM_ATTR_TYPE_NONE,
156                             TEE_PARAM_ATTR_TYPE_NONE, TEE_PARAM_ATTR_TYPE_NONE,
157                             num_params, params);
158 }
159
160 static u32 ta_avb_invoke_func(struct udevice *dev, u32 func, uint num_params,
161                               struct tee_param *params)
162 {
163         struct sandbox_tee_state *state = dev_get_priv(dev);
164         struct env_entry e, *ep;
165         char *name;
166         u32 res;
167         uint slot;
168         u64 val;
169         char *value;
170         u32 value_sz;
171
172         switch (func) {
173         case TA_AVB_CMD_READ_ROLLBACK_INDEX:
174                 res = check_params(TEE_PARAM_ATTR_TYPE_VALUE_INPUT,
175                                    TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT,
176                                    TEE_PARAM_ATTR_TYPE_NONE,
177                                    TEE_PARAM_ATTR_TYPE_NONE,
178                                    num_params, params);
179                 if (res)
180                         return res;
181
182                 slot = params[0].u.value.a;
183                 if (slot >= ARRAY_SIZE(state->ta_avb_rollback_indexes)) {
184                         printf("Rollback index slot out of bounds %u\n", slot);
185                         return TEE_ERROR_BAD_PARAMETERS;
186                 }
187
188                 val = state->ta_avb_rollback_indexes[slot];
189                 params[1].u.value.a = val >> 32;
190                 params[1].u.value.b = val;
191                 return TEE_SUCCESS;
192
193         case TA_AVB_CMD_WRITE_ROLLBACK_INDEX:
194                 res = check_params(TEE_PARAM_ATTR_TYPE_VALUE_INPUT,
195                                    TEE_PARAM_ATTR_TYPE_VALUE_INPUT,
196                                    TEE_PARAM_ATTR_TYPE_NONE,
197                                    TEE_PARAM_ATTR_TYPE_NONE,
198                                    num_params, params);
199                 if (res)
200                         return res;
201
202                 slot = params[0].u.value.a;
203                 if (slot >= ARRAY_SIZE(state->ta_avb_rollback_indexes)) {
204                         printf("Rollback index slot out of bounds %u\n", slot);
205                         return TEE_ERROR_BAD_PARAMETERS;
206                 }
207
208                 val = (u64)params[1].u.value.a << 32 | params[1].u.value.b;
209                 if (val < state->ta_avb_rollback_indexes[slot])
210                         return TEE_ERROR_SECURITY;
211
212                 state->ta_avb_rollback_indexes[slot] = val;
213                 return TEE_SUCCESS;
214
215         case TA_AVB_CMD_READ_LOCK_STATE:
216                 res = check_params(TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT,
217                                    TEE_PARAM_ATTR_TYPE_NONE,
218                                    TEE_PARAM_ATTR_TYPE_NONE,
219                                    TEE_PARAM_ATTR_TYPE_NONE,
220                                    num_params, params);
221                 if (res)
222                         return res;
223
224                 params[0].u.value.a = state->ta_avb_lock_state;
225                 return TEE_SUCCESS;
226
227         case TA_AVB_CMD_WRITE_LOCK_STATE:
228                 res = check_params(TEE_PARAM_ATTR_TYPE_VALUE_INPUT,
229                                    TEE_PARAM_ATTR_TYPE_NONE,
230                                    TEE_PARAM_ATTR_TYPE_NONE,
231                                    TEE_PARAM_ATTR_TYPE_NONE,
232                                    num_params, params);
233                 if (res)
234                         return res;
235
236                 if (state->ta_avb_lock_state != params[0].u.value.a) {
237                         state->ta_avb_lock_state = params[0].u.value.a;
238                         memset(state->ta_avb_rollback_indexes, 0,
239                                sizeof(state->ta_avb_rollback_indexes));
240                 }
241
242                 return TEE_SUCCESS;
243         case TA_AVB_CMD_READ_PERSIST_VALUE:
244                 res = check_params(TEE_PARAM_ATTR_TYPE_MEMREF_INPUT,
245                                    TEE_PARAM_ATTR_TYPE_MEMREF_INOUT,
246                                    TEE_PARAM_ATTR_TYPE_NONE,
247                                    TEE_PARAM_ATTR_TYPE_NONE,
248                                    num_params, params);
249                 if (res)
250                         return res;
251
252                 name = params[0].u.memref.shm->addr;
253
254                 value = params[1].u.memref.shm->addr;
255                 value_sz = params[1].u.memref.size;
256
257                 e.key = name;
258                 e.data = NULL;
259                 hsearch_r(e, ENV_FIND, &ep, &state->pstorage_htab, 0);
260                 if (!ep)
261                         return TEE_ERROR_ITEM_NOT_FOUND;
262
263                 value_sz = strlen(ep->data) + 1;
264                 memcpy(value, ep->data, value_sz);
265
266                 return TEE_SUCCESS;
267         case TA_AVB_CMD_WRITE_PERSIST_VALUE:
268                 res = check_params(TEE_PARAM_ATTR_TYPE_MEMREF_INPUT,
269                                    TEE_PARAM_ATTR_TYPE_MEMREF_INPUT,
270                                    TEE_PARAM_ATTR_TYPE_NONE,
271                                    TEE_PARAM_ATTR_TYPE_NONE,
272                                    num_params, params);
273                 if (res)
274                         return res;
275
276                 name = params[0].u.memref.shm->addr;
277
278                 value = params[1].u.memref.shm->addr;
279                 value_sz = params[1].u.memref.size;
280
281                 e.key = name;
282                 e.data = NULL;
283                 hsearch_r(e, ENV_FIND, &ep, &state->pstorage_htab, 0);
284                 if (ep)
285                         hdelete_r(e.key, &state->pstorage_htab, 0);
286
287                 e.key = name;
288                 e.data = value;
289                 hsearch_r(e, ENV_ENTER, &ep, &state->pstorage_htab, 0);
290                 if (!ep)
291                         return TEE_ERROR_OUT_OF_MEMORY;
292
293                 return TEE_SUCCESS;
294
295         default:
296                 return TEE_ERROR_NOT_SUPPORTED;
297         }
298 }
299 #endif /* OPTEE_TA_AVB */
300
301 #ifdef CONFIG_OPTEE_TA_RPC_TEST
302 static u32 ta_rpc_test_open_session(struct udevice *dev, uint num_params,
303                                     struct tee_param *params)
304 {
305         /*
306          * We don't expect additional parameters when opening a session to
307          * this TA.
308          */
309         return check_params(TEE_PARAM_ATTR_TYPE_NONE, TEE_PARAM_ATTR_TYPE_NONE,
310                             TEE_PARAM_ATTR_TYPE_NONE, TEE_PARAM_ATTR_TYPE_NONE,
311                             num_params, params);
312 }
313
314 static void fill_i2c_rpc_params(struct optee_msg_arg *msg_arg, u64 bus_num,
315                                 u64 chip_addr, u64 xfer_flags, u64 op,
316                                 struct tee_param_memref memref)
317 {
318         msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
319         msg_arg->params[1].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
320         msg_arg->params[2].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INOUT;
321         msg_arg->params[3].attr = OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT;
322
323         /* trigger I2C services of TEE supplicant */
324         msg_arg->cmd = OPTEE_MSG_RPC_CMD_I2C_TRANSFER;
325
326         msg_arg->params[0].u.value.a = op;
327         msg_arg->params[0].u.value.b = bus_num;
328         msg_arg->params[0].u.value.c = chip_addr;
329         msg_arg->params[1].u.value.a = xfer_flags;
330
331         /* buffer to read/write data */
332         msg_arg->params[2].u.rmem.shm_ref = (ulong)memref.shm;
333         msg_arg->params[2].u.rmem.size = memref.size;
334         msg_arg->params[2].u.rmem.offs = memref.shm_offs;
335
336         msg_arg->num_params = 4;
337 }
338
339 static u32 ta_rpc_test_invoke_func(struct udevice *dev, u32 func,
340                                    uint num_params,
341                                    struct tee_param *params)
342 {
343         struct tee_shm *shm;
344         struct tee_param_memref memref_data;
345         struct optee_msg_arg *msg_arg;
346         int chip_addr, bus_num, op, xfer_flags;
347         int res;
348
349         res = check_params(TEE_PARAM_ATTR_TYPE_VALUE_INPUT,
350                            TEE_PARAM_ATTR_TYPE_MEMREF_INOUT,
351                            TEE_PARAM_ATTR_TYPE_NONE,
352                            TEE_PARAM_ATTR_TYPE_NONE,
353                            num_params, params);
354         if (res)
355                 return TEE_ERROR_BAD_PARAMETERS;
356
357         bus_num = params[0].u.value.a;
358         chip_addr = params[0].u.value.b;
359         xfer_flags = params[0].u.value.c;
360         memref_data = params[1].u.memref;
361
362         switch (func) {
363         case TA_RPC_TEST_CMD_I2C_READ:
364                 op = OPTEE_MSG_RPC_CMD_I2C_TRANSFER_RD;
365                 break;
366         case TA_RPC_TEST_CMD_I2C_WRITE:
367                 op = OPTEE_MSG_RPC_CMD_I2C_TRANSFER_WR;
368                 break;
369         default:
370                 return TEE_ERROR_NOT_SUPPORTED;
371         }
372
373         /*
374          * Fill params for an RPC call to tee supplicant
375          */
376         res = get_msg_arg(dev, 4, &shm, &msg_arg);
377         if (res)
378                 goto out;
379
380         fill_i2c_rpc_params(msg_arg, bus_num, chip_addr, xfer_flags, op,
381                             memref_data);
382
383         /* Make an RPC call to tee supplicant */
384         optee_suppl_cmd(dev, shm, 0);
385         res = msg_arg->ret;
386 out:
387         tee_shm_free(shm);
388
389         return res;
390 }
391 #endif /* CONFIG_OPTEE_TA_RPC_TEST */
392
393 static const struct ta_entry ta_entries[] = {
394 #ifdef CONFIG_OPTEE_TA_AVB
395         { .uuid = TA_AVB_UUID,
396           .open_session = ta_avb_open_session,
397           .invoke_func = ta_avb_invoke_func,
398         },
399 #endif
400 #ifdef CONFIG_OPTEE_TA_RPC_TEST
401         { .uuid = TA_RPC_TEST_UUID,
402           .open_session = ta_rpc_test_open_session,
403           .invoke_func = ta_rpc_test_invoke_func,
404         },
405 #endif
406 #ifdef CONFIG_OPTEE_TA_SCP03
407         { .uuid = PTA_SCP03_UUID,
408           .open_session = pta_scp03_open_session,
409           .invoke_func = pta_scp03_invoke_func,
410         },
411 #endif
412 };
413
414 static void sandbox_tee_get_version(struct udevice *dev,
415                                     struct tee_version_data *vers)
416 {
417         struct tee_version_data v = {
418                 .gen_caps = TEE_GEN_CAP_GP | TEE_GEN_CAP_REG_MEM,
419         };
420
421         *vers = v;
422 }
423
424 static int sandbox_tee_close_session(struct udevice *dev, u32 session)
425 {
426         struct sandbox_tee_state *state = dev_get_priv(dev);
427
428         if (!state->ta || state->session != session)
429                 return -EINVAL;
430
431         state->session = 0;
432         state->ta = NULL;
433
434         return 0;
435 }
436
437 static const struct ta_entry *find_ta_entry(u8 uuid[TEE_UUID_LEN])
438 {
439         struct tee_optee_ta_uuid u;
440         uint n;
441
442         tee_optee_ta_uuid_from_octets(&u, uuid);
443
444         for (n = 0; n < ARRAY_SIZE(ta_entries); n++)
445                 if (!memcmp(&u, &ta_entries[n].uuid, sizeof(u)))
446                         return ta_entries + n;
447
448         return NULL;
449 }
450
451 static int sandbox_tee_open_session(struct udevice *dev,
452                                     struct tee_open_session_arg *arg,
453                                     uint num_params, struct tee_param *params)
454 {
455         struct sandbox_tee_state *state = dev_get_priv(dev);
456         const struct ta_entry *ta;
457
458         if (state->ta) {
459                 printf("A session is already open\n");
460                 return -EBUSY;
461         }
462
463         ta = find_ta_entry(arg->uuid);
464         if (!ta) {
465                 printf("Cannot find TA\n");
466                 arg->ret = TEE_ERROR_ITEM_NOT_FOUND;
467                 arg->ret_origin = TEE_ORIGIN_TEE;
468
469                 return 0;
470         }
471
472         arg->ret = ta->open_session(dev, num_params, params);
473         arg->ret_origin = TEE_ORIGIN_TRUSTED_APP;
474
475         if (!arg->ret) {
476                 state->ta = (void *)ta;
477                 state->session = 1;
478                 arg->session = state->session;
479         } else {
480                 printf("Cannot open session, TA returns error\n");
481         }
482
483         return 0;
484 }
485
486 static int sandbox_tee_invoke_func(struct udevice *dev,
487                                    struct tee_invoke_arg *arg,
488                                    uint num_params, struct tee_param *params)
489 {
490         struct sandbox_tee_state *state = dev_get_priv(dev);
491         struct ta_entry *ta = state->ta;
492
493         if (!arg->session) {
494                 printf("Missing session\n");
495                 return -EINVAL;
496         }
497
498         if (!ta) {
499                 printf("TA session not available\n");
500                 return -EINVAL;
501         }
502
503         if (arg->session != state->session) {
504                 printf("Session mismatch\n");
505                 return -EINVAL;
506         }
507
508         arg->ret = ta->invoke_func(dev, arg->func, num_params, params);
509         arg->ret_origin = TEE_ORIGIN_TRUSTED_APP;
510
511         return 0;
512 }
513
514 static int sandbox_tee_shm_register(struct udevice *dev, struct tee_shm *shm)
515 {
516         struct sandbox_tee_state *state = dev_get_priv(dev);
517
518         state->num_shms++;
519
520         return 0;
521 }
522
523 static int sandbox_tee_shm_unregister(struct udevice *dev, struct tee_shm *shm)
524 {
525         struct sandbox_tee_state *state = dev_get_priv(dev);
526
527         state->num_shms--;
528
529         return 0;
530 }
531
532 static int sandbox_tee_remove(struct udevice *dev)
533 {
534         struct sandbox_tee_state *state = dev_get_priv(dev);
535
536         hdestroy_r(&state->pstorage_htab);
537
538         return 0;
539 }
540
541 static int sandbox_tee_probe(struct udevice *dev)
542 {
543         struct sandbox_tee_state *state = dev_get_priv(dev);
544         /*
545          * With this hastable we emulate persistent storage,
546          * which should contain persistent values
547          * between different sessions/command invocations.
548          */
549         if (!hcreate_r(pstorage_max, &state->pstorage_htab))
550                 return TEE_ERROR_OUT_OF_MEMORY;
551
552         return 0;
553 }
554
555 static const struct tee_driver_ops sandbox_tee_ops = {
556         .get_version = sandbox_tee_get_version,
557         .open_session = sandbox_tee_open_session,
558         .close_session = sandbox_tee_close_session,
559         .invoke_func = sandbox_tee_invoke_func,
560         .shm_register = sandbox_tee_shm_register,
561         .shm_unregister = sandbox_tee_shm_unregister,
562 };
563
564 static const struct udevice_id sandbox_tee_match[] = {
565         { .compatible = "sandbox,tee" },
566         {},
567 };
568
569 U_BOOT_DRIVER(sandbox_tee) = {
570         .name = "sandbox_tee",
571         .id = UCLASS_TEE,
572         .of_match = sandbox_tee_match,
573         .ops = &sandbox_tee_ops,
574         .priv_auto      = sizeof(struct sandbox_tee_state),
575         .probe = sandbox_tee_probe,
576         .remove = sandbox_tee_remove,
577 };