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
27namespace OHOS {
28const std::u16string INTERFACE_TOKEN = u"ohos.tee_client.accessToken";
29using 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 */
37enum {
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
51class TeeClient {
52public:
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:
74        explicit DeathNotifier(const sptr<IRemoteObject> &deathNotify) : serviceBinder(deathNotify)
75        {
76        }
77        virtual ~DeathNotifier()
78        {
79            if (mServiceValid && (serviceBinder != nullptr)) {
80                serviceBinder->RemoveDeathRecipient(this);
81            }
82        }
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
96private:
97    TeeClient() : mTeecService(nullptr), mDeathNotifier(nullptr), mNotify(nullptr)
98    {
99        tloge("Init TeeClient\n");
100    }
101
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