1 /*
2  * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3  * Licensed under the Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *     http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9  * PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  */
12 
13 #ifndef TEE_CLIENT_H
14 #define TEE_CLIENT_H
15 
16 #include <cstdint>
17 #include <cstdio>
18 #include <mutex>
19 #include "ashmem.h"
20 #include "ipc_types.h"
21 #include "iremote_proxy.h"
22 #include "iremote_stub.h"
23 #include "tee_client_api.h"
24 #include "tee_client_inner.h"
25 #include "tee_log.h"
26 
27 namespace OHOS {
28 const std::u16string INTERFACE_TOKEN = u"ohos.tee_client.accessToken";
29 using TC_NS_ShareMem = struct {
30     uint32_t offset;
31     void *buffer;
32     uint32_t size;
33     int32_t fd; /* Used to mark which context sharemem belongs to */
34 };
35 
36 /* keep same with cadaemon interface defines */
37 enum {
38     INIT_CONTEXT = 0,
39     FINAL_CONTEXT,
40     OPEN_SESSION,
41     CLOSE_SESSION,
42     INVOKE_COMMND,
43     REGISTER_MEM,
44     ALLOC_MEM,
45     RELEASE_MEM,
46     SET_CALL_BACK,
47     SEND_SECFILE,
48     GET_TEE_VERSION
49 };
50 
51 class TeeClient {
52 public:
GetInstance()53     static TeeClient &GetInstance()
54     {
55         static TeeClient instance;
56         return instance;
57     }
58     TEEC_Result InitializeContext(const char *name, TEEC_Context *context);
59     void FinalizeContext(TEEC_Context *context);
60     TEEC_Result OpenSession(TEEC_Context *context, TEEC_Session *session, const TEEC_UUID *destination,
61         uint32_t connectionMethod, const void *connectionData, TEEC_Operation *operation, uint32_t *returnOrigin);
62     void CloseSession(TEEC_Session *session);
63     TEEC_Result InvokeCommand(TEEC_Session *session, uint32_t commandID,
64         TEEC_Operation *operation, uint32_t *returnOrigin);
65     TEEC_Result RegisterSharedMemory(TEEC_Context *context, TEEC_SharedMemory *sharedMem);
66     TEEC_Result AllocateSharedMemory(TEEC_Context *context, TEEC_SharedMemory *sharedMem);
67     void ReleaseSharedMemory(TEEC_SharedMemory *sharedMem);
68     void RequestCancellation(const TEEC_Operation *operation);
69     TEEC_Result SendSecfile(const char *path, TEEC_Session *session);
70     TEEC_Result GetTeeVersion(uint32_t &teeVersion);
71 
72     class DeathNotifier : public IRemoteObject::DeathRecipient {
73     public:
DeathNotifier(const sptr<IRemoteObject> & deathNotify)74         explicit DeathNotifier(const sptr<IRemoteObject> &deathNotify) : serviceBinder(deathNotify)
75         {
76         }
~DeathNotifier()77         virtual ~DeathNotifier()
78         {
79             if (mServiceValid && (serviceBinder != nullptr)) {
80                 serviceBinder->RemoveDeathRecipient(this);
81             }
82         }
OnRemoteDied(const wptr<IRemoteObject> & deathNotify)83         virtual void OnRemoteDied(const wptr<IRemoteObject> &deathNotify)
84         {
85             (void)deathNotify;
86             tloge("teec service died");
87             mServiceValid = false;
88         }
89 
90     private:
91         sptr<IRemoteObject> serviceBinder;
92     };
93 
94     friend class DeathNotifier;
95 
96 private:
TeeClient()97     TeeClient() : mTeecService(nullptr), mDeathNotifier(nullptr), mNotify(nullptr)
98     {
99         tloge("Init TeeClient\n");
100     }
101 
~TeeClient()102     ~TeeClient()
103     {
104         FreeAllShareMem();
105         tloge("TeeClient Destroy\n");
106     }
107 
108     TeeClient(const TeeClient &) = delete;
109     TeeClient &operator=(const TeeClient &) = delete;
110 
111     void InitTeecService();
112     bool SetCallBack();
113     int32_t GetFileFd(const char *filePath);
114     TEEC_Result InitializeContextSendCmd(const char *name, MessageParcel &reply);
115     TEEC_Result OpenSessionSendCmd(TEEC_Context *context, TEEC_Session *session, const TEEC_UUID *destination,
116         uint32_t connectionMethod, int32_t fd, TEEC_Operation *operation, uint32_t *retOrigin);
117     bool FormatSession(TEEC_Session *session, MessageParcel &reply);
118     TEEC_Result InvokeCommandSendCmd(TEEC_Context *context, TEEC_Session *session, uint32_t commandID,
119     TEEC_Operation *operation, uint32_t *returnOrigin);
120     TEEC_Result GetOptMemSize(TEEC_Operation *operation, size_t *memSize);
121     TEEC_Result GetPartialMemSize(TEEC_Operation *operation, size_t optMemSize,
122         uint32_t paramCnt, uint32_t *cSize);
123     TEEC_Result CopyTeecOptMem(TEEC_Operation *operation, size_t optMemSize, sptr<Ashmem> &optMem);
124     TEEC_Result TeecOptEncode(TEEC_Operation *operation, sptr<Ashmem> &optMem, size_t dataSize);
125     TEEC_Result TeecOptEncodeTempMem(const TEEC_Parameter *param, sptr<Ashmem> &optMem, size_t *dataSize);
126     TEEC_Result GetTeecOptMem(TEEC_Operation *operation, size_t optMemSize, sptr<Ashmem> &optMem, MessageParcel &reply);
127     TEEC_Result TeecOptDecode(TEEC_Operation *operation, TEEC_Operation *inOpt, const uint8_t *data, size_t dataSize);
128     TEEC_Result TeecOptDecodeTempMem(TEEC_Parameter *param, uint32_t paramType, const TEEC_Parameter *inParam,
129         const uint8_t **data, size_t *dataSize);
130     TEEC_Result TeecOptDecodePartialMem(TEEC_Parameter *param, uint32_t paramType,
131         TEEC_Parameter *inParam, const uint8_t **data, size_t *dataSize);
132     TEEC_Result TeecOptEncodePartialMem(const TEEC_Parameter *param,
133         uint32_t paramType, sptr<Ashmem> &optMem, size_t *dataSize);
134     bool CovertEncodePtr(sptr<Ashmem> &optMem, size_t *sizeLeft, TEEC_SharedMemory *shm);
135     TEEC_Result FormatSharedMemory(MessageParcel &reply, TEEC_SharedMemory *sharedMem, uint32_t *offset);
136     TEEC_Result MapSharedMemory(int fd, uint32_t offset, TEEC_SharedMemory *sharedMem);
137     TEEC_Result ProcAllocateSharedMemory(MessageParcel &reply, TEEC_SharedMemory *sharedMem);
138     uint32_t FindShareMemOffset(const void *buffer);
139     void AddShareMem(void *buffer, uint32_t offset, uint32_t size, int32_t fd);
140     void FreeAllShareMem();
141     void FreeAllShareMemoryInContext(const TEEC_Context *context);
142     TEEC_Result FreeShareMem(TEEC_SharedMemory *sharedMem);
143     TEEC_Result TEEC_CheckOperation(const TEEC_Operation *operation);
144 
145     std::mutex mServiceLock;
146     std::mutex mSharMemLock;
147     static bool mServiceValid;
148     sptr<IRemoteObject> mTeecService;
149     sptr<DeathNotifier> mDeathNotifier;
150     sptr<IRemoteObject> mNotify;
151     std::vector<TC_NS_ShareMem> mShareMem;
152 };
153 } // namespace OHOS
154 #endif
155