15843bb75SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
25843bb75SJerome Forissier /*
35843bb75SJerome Forissier * Copyright (C) 2019, Linaro Limited
45843bb75SJerome Forissier */
55843bb75SJerome Forissier
65843bb75SJerome Forissier /*
75843bb75SJerome Forissier * This pseudo TA is used by normal world OS TEE driver to fetch pseudo TA's
85843bb75SJerome Forissier * UUIDs which can act as TEE bus devices.
95843bb75SJerome Forissier */
105843bb75SJerome Forissier
119389d803SMaxim Uvarov #include <config.h>
129389d803SMaxim Uvarov #include <kernel/early_ta.h>
139389d803SMaxim Uvarov #include <kernel/linker.h>
145843bb75SJerome Forissier #include <kernel/pseudo_ta.h>
158f31ccb0SJens Wiklander #include <kernel/stmm_sp.h>
165843bb75SJerome Forissier #include <kernel/tee_ta_manager.h>
175843bb75SJerome Forissier #include <pta_device.h>
18a96033caSJens Wiklander #include <tee/tee_fs.h>
195843bb75SJerome Forissier #include <tee/uuid.h>
205843bb75SJerome Forissier #include <user_ta_header.h>
215843bb75SJerome Forissier
225843bb75SJerome Forissier #define PTA_NAME "device.pta"
235843bb75SJerome Forissier
add_ta(uint32_t flags,const TEE_UUID * uuid,uint8_t * buf,uint32_t blen,uint32_t * pos,uint32_t rflags)249389d803SMaxim Uvarov static void add_ta(uint32_t flags, const TEE_UUID *uuid, uint8_t *buf,
25bc5921cdSMaxim Uvarov uint32_t blen, uint32_t *pos, uint32_t rflags)
269389d803SMaxim Uvarov {
27a96033caSJens Wiklander flags &= (TA_FLAG_DEVICE_ENUM | TA_FLAG_DEVICE_ENUM_SUPP |
28a96033caSJens Wiklander TA_FLAG_DEVICE_ENUM_TEE_STORAGE_PRIVATE);
29a96033caSJens Wiklander if (flags && flags != TA_FLAG_DEVICE_ENUM &&
30a96033caSJens Wiklander flags != TA_FLAG_DEVICE_ENUM_SUPP &&
31a96033caSJens Wiklander flags != TA_FLAG_DEVICE_ENUM_TEE_STORAGE_PRIVATE) {
32bc5921cdSMaxim Uvarov EMSG(PTA_NAME ": skipping TA %pUl, inconsistent flags", uuid);
33bc5921cdSMaxim Uvarov return;
34bc5921cdSMaxim Uvarov }
35bc5921cdSMaxim Uvarov
36bc5921cdSMaxim Uvarov if (flags & rflags) {
379389d803SMaxim Uvarov if (*pos + sizeof(*uuid) <= blen)
389389d803SMaxim Uvarov tee_uuid_to_octets(buf + *pos, uuid);
399389d803SMaxim Uvarov
409389d803SMaxim Uvarov *pos += sizeof(*uuid);
419389d803SMaxim Uvarov }
429389d803SMaxim Uvarov }
439389d803SMaxim Uvarov
get_devices(uint32_t types,TEE_Param params[TEE_NUM_PARAMS],uint32_t rflags)445843bb75SJerome Forissier static TEE_Result get_devices(uint32_t types,
45bc5921cdSMaxim Uvarov TEE_Param params[TEE_NUM_PARAMS],
46bc5921cdSMaxim Uvarov uint32_t rflags)
475843bb75SJerome Forissier {
489389d803SMaxim Uvarov const struct pseudo_ta_head *ta = NULL;
49880d8d8eSJelle Sels const struct embedded_ts *eta = NULL;
509389d803SMaxim Uvarov void *buf = NULL;
519389d803SMaxim Uvarov uint32_t blen = 0;
529389d803SMaxim Uvarov uint32_t pos = 0;
535843bb75SJerome Forissier
545843bb75SJerome Forissier if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT,
555843bb75SJerome Forissier TEE_PARAM_TYPE_NONE,
565843bb75SJerome Forissier TEE_PARAM_TYPE_NONE,
575843bb75SJerome Forissier TEE_PARAM_TYPE_NONE))
585843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
595843bb75SJerome Forissier
605843bb75SJerome Forissier if (!params[0].memref.buffer && (params[0].memref.size > 0))
615843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
625843bb75SJerome Forissier
639389d803SMaxim Uvarov buf = params[0].memref.buffer;
649389d803SMaxim Uvarov blen = params[0].memref.size;
655843bb75SJerome Forissier
669389d803SMaxim Uvarov SCATTERED_ARRAY_FOREACH(ta, pseudo_tas, struct pseudo_ta_head)
67bc5921cdSMaxim Uvarov add_ta(ta->flags, &ta->uuid, buf, blen, &pos, rflags);
685843bb75SJerome Forissier
698f31ccb0SJens Wiklander if (stmm_get_uuid())
70*b89bfe57SJan Kiszka add_ta(TA_FLAG_DEVICE_ENUM_TEE_STORAGE_PRIVATE,
71*b89bfe57SJan Kiszka stmm_get_uuid(), buf, blen, &pos, rflags);
728f31ccb0SJens Wiklander
739389d803SMaxim Uvarov if (IS_ENABLED(CFG_EARLY_TA))
749389d803SMaxim Uvarov for_each_early_ta(eta)
75bc5921cdSMaxim Uvarov add_ta(eta->flags, &eta->uuid, buf, blen, &pos,
76bc5921cdSMaxim Uvarov rflags);
775843bb75SJerome Forissier
789389d803SMaxim Uvarov params[0].memref.size = pos;
799389d803SMaxim Uvarov if (pos > blen)
809389d803SMaxim Uvarov return TEE_ERROR_SHORT_BUFFER;
819389d803SMaxim Uvarov
829389d803SMaxim Uvarov return TEE_SUCCESS;
835843bb75SJerome Forissier }
845843bb75SJerome Forissier
invoke_command(void * pSessionContext __unused,uint32_t nCommandID,uint32_t nParamTypes,TEE_Param pParams[TEE_NUM_PARAMS])855843bb75SJerome Forissier static TEE_Result invoke_command(void *pSessionContext __unused,
865843bb75SJerome Forissier uint32_t nCommandID, uint32_t nParamTypes,
875843bb75SJerome Forissier TEE_Param pParams[TEE_NUM_PARAMS])
885843bb75SJerome Forissier {
89a96033caSJens Wiklander TEE_Result res = TEE_SUCCESS;
90a96033caSJens Wiklander uint32_t rflags = 0;
910ed372c6SJerome Forissier /*
920ed372c6SJerome Forissier * This should also be true if CFG_RPMB_ANNOUNCE_PROBE_CAP is
930ed372c6SJerome Forissier * enabled when the kernel does not support OP-TEE RPMB operations.
940ed372c6SJerome Forissier */
950ed372c6SJerome Forissier bool rpmb_needs_supp = !IS_ENABLED(CFG_RPMB_ANNOUNCE_PROBE_CAP);
96a96033caSJens Wiklander
975843bb75SJerome Forissier switch (nCommandID) {
985843bb75SJerome Forissier case PTA_CMD_GET_DEVICES:
99a96033caSJens Wiklander rflags = TA_FLAG_DEVICE_ENUM;
1005843bb75SJerome Forissier break;
101a96033caSJens Wiklander case PTA_CMD_GET_DEVICES_SUPP:
102a96033caSJens Wiklander rflags = TA_FLAG_DEVICE_ENUM_SUPP;
1030ed372c6SJerome Forissier if (IS_ENABLED(CFG_REE_FS) ||
1040ed372c6SJerome Forissier (IS_ENABLED(CFG_RPMB_FS) && rpmb_needs_supp))
105a96033caSJens Wiklander rflags |= TA_FLAG_DEVICE_ENUM_TEE_STORAGE_PRIVATE;
106a96033caSJens Wiklander break;
107a96033caSJens Wiklander case PTA_CMD_GET_DEVICES_RPMB:
108a96033caSJens Wiklander if (!IS_ENABLED(CFG_REE_FS)) {
109a96033caSJens Wiklander res = tee_rpmb_reinit();
110a96033caSJens Wiklander if (res)
111a96033caSJens Wiklander return TEE_ERROR_STORAGE_NOT_AVAILABLE;
112a96033caSJens Wiklander rflags = TA_FLAG_DEVICE_ENUM_TEE_STORAGE_PRIVATE;
113a96033caSJens Wiklander }
114a96033caSJens Wiklander break;
115a96033caSJens Wiklander default:
116a96033caSJens Wiklander return TEE_ERROR_NOT_IMPLEMENTED;
1175843bb75SJerome Forissier }
1185843bb75SJerome Forissier
119a96033caSJens Wiklander return get_devices(nParamTypes, pParams, rflags);
1205843bb75SJerome Forissier }
1215843bb75SJerome Forissier
1225843bb75SJerome Forissier pseudo_ta_register(.uuid = PTA_DEVICE_UUID, .name = PTA_NAME,
1235843bb75SJerome Forissier .flags = PTA_DEFAULT_FLAGS,
1245843bb75SJerome Forissier .invoke_command_entry_point = invoke_command);
125