1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "resource_node.h"
17 
18 #include <cinttypes>
19 #include <mutex>
20 #include <unordered_map>
21 
22 #include "device_manager_util.h"
23 #include "hdi_wrapper.h"
24 #include "iam_check.h"
25 #include "iam_common_defines.h"
26 #include "iam_logger.h"
27 #include "iam_ptr.h"
28 #include "remote_msg_util.h"
29 
30 #define LOG_TAG "USER_AUTH_SA"
31 
32 namespace OHOS {
33 namespace UserIam {
34 namespace UserAuth {
35 class ResourceNodeImpl : public ResourceNode, public NoCopyable {
36 public:
37     ResourceNodeImpl(ExecutorRegisterInfo info, std::shared_ptr<ExecutorCallbackInterface> callback);
38     ~ResourceNodeImpl() override;
39 
40     uint64_t GetExecutorIndex() const override;
41     std::string GetOwnerDeviceId() const override;
42     uint32_t GetOwnerPid() const override;
43     AuthType GetAuthType() const override;
44     ExecutorRole GetExecutorRole() const override;
45     uint64_t GetExecutorSensorHint() const override;
46     uint64_t GetExecutorMatcher() const override;
47     ExecutorSecureLevel GetExecutorEsl() const override;
48     std::vector<uint8_t> GetExecutorPublicKey() const override;
49     std::string GetExecutorDeviceUdid() const override;
50 
51     int32_t BeginExecute(uint64_t scheduleId, const std::vector<uint8_t> &publicKey,
52         const Attributes &command) override;
53     int32_t EndExecute(uint64_t scheduleId, const Attributes &command) override;
54     int32_t SetProperty(const Attributes &properties) override;
55     int32_t GetProperty(const Attributes &condition, Attributes &values) override;
56     int32_t SendData(uint64_t scheduleId, const Attributes &data) override;
57     void DeleteFromDriver() override;
58     void DetachFromDriver() override;
59     friend ResourceNode;
60 
61 private:
62     int32_t AddToDriver(std::vector<uint64_t> &templateIdList, std::vector<uint8_t> &fwkPublicKey);
63     static void DeleteExecutorFromDriver(uint64_t executorIndex);
64 
65     ExecutorRegisterInfo info_;
66     std::shared_ptr<ExecutorCallbackInterface> callback_;
67     uint64_t executorIndex_ {0};
68     std::recursive_mutex mutex_;
69     bool addedToDriver_ {false};
70 };
71 
ResourceNodeImpl(ExecutorRegisterInfo info,std::shared_ptr<ExecutorCallbackInterface> callback)72 ResourceNodeImpl::ResourceNodeImpl(ExecutorRegisterInfo info, std::shared_ptr<ExecutorCallbackInterface> callback)
73     : info_(std::move(info)),
74       callback_(std::move(callback))
75 {
76     if (info_.deviceUdid.empty()) {
77         bool setUdidRet = DeviceManagerUtil::GetInstance().GetLocalDeviceUdid(info_.deviceUdid);
78         IF_FALSE_LOGE_AND_RETURN(setUdidRet);
79     }
80 }
81 
~ResourceNodeImpl()82 ResourceNodeImpl::~ResourceNodeImpl()
83 {
84     if (!addedToDriver_) {
85         return;
86     }
87 
88     DeleteExecutorFromDriver(executorIndex_);
89 }
90 
GetExecutorIndex() const91 uint64_t ResourceNodeImpl::GetExecutorIndex() const
92 {
93     return executorIndex_;
94 }
95 
GetOwnerDeviceId() const96 std::string ResourceNodeImpl::GetOwnerDeviceId() const
97 {
98     return {};
99 }
100 
GetOwnerPid() const101 uint32_t ResourceNodeImpl::GetOwnerPid() const
102 {
103     return SUCCESS;
104 }
105 
GetAuthType() const106 AuthType ResourceNodeImpl::GetAuthType() const
107 {
108     return info_.authType;
109 }
110 
GetExecutorRole() const111 ExecutorRole ResourceNodeImpl::GetExecutorRole() const
112 {
113     return info_.executorRole;
114 }
115 
GetExecutorSensorHint() const116 uint64_t ResourceNodeImpl::GetExecutorSensorHint() const
117 {
118     return info_.executorSensorHint;
119 }
120 
GetExecutorMatcher() const121 uint64_t ResourceNodeImpl::GetExecutorMatcher() const
122 {
123     return info_.executorMatcher;
124 }
125 
GetExecutorEsl() const126 ExecutorSecureLevel ResourceNodeImpl::GetExecutorEsl() const
127 {
128     return info_.esl;
129 }
130 
GetExecutorPublicKey() const131 std::vector<uint8_t> ResourceNodeImpl::GetExecutorPublicKey() const
132 {
133     return info_.publicKey;
134 }
135 
GetExecutorDeviceUdid() const136 std::string ResourceNodeImpl::GetExecutorDeviceUdid() const
137 {
138     return info_.deviceUdid;
139 }
140 
BeginExecute(uint64_t scheduleId,const std::vector<uint8_t> & publicKey,const Attributes & command)141 int32_t ResourceNodeImpl::BeginExecute(uint64_t scheduleId, const std::vector<uint8_t> &publicKey,
142     const Attributes &command)
143 {
144     IAM_LOGI("start");
145     if (callback_ != nullptr) {
146         return callback_->OnBeginExecute(scheduleId, publicKey, command);
147     }
148     return GENERAL_ERROR;
149 }
150 
EndExecute(uint64_t scheduleId,const Attributes & command)151 int32_t ResourceNodeImpl::EndExecute(uint64_t scheduleId, const Attributes &command)
152 {
153     IAM_LOGI("start");
154     if (callback_ != nullptr) {
155         return callback_->OnEndExecute(scheduleId, command);
156     }
157     return GENERAL_ERROR;
158 }
159 
SetProperty(const Attributes & properties)160 int32_t ResourceNodeImpl::SetProperty(const Attributes &properties)
161 {
162     IAM_LOGI("start");
163     if (callback_ != nullptr) {
164         return callback_->OnSetProperty(properties);
165     }
166     return GENERAL_ERROR;
167 }
168 
GetProperty(const Attributes & condition,Attributes & values)169 int32_t ResourceNodeImpl::GetProperty(const Attributes &condition, Attributes &values)
170 {
171     IAM_LOGI("start");
172     if (callback_ != nullptr) {
173         return callback_->OnGetProperty(condition, values);
174     }
175     return GENERAL_ERROR;
176 }
177 
SendData(uint64_t scheduleId,const Attributes & data)178 int32_t ResourceNodeImpl::SendData(uint64_t scheduleId, const Attributes &data)
179 {
180     IAM_LOGI("start");
181 
182     if (callback_ != nullptr) {
183         return callback_->OnSendData(scheduleId, data);
184     }
185     return GENERAL_ERROR;
186 }
187 
DeleteFromDriver()188 void ResourceNodeImpl::DeleteFromDriver()
189 {
190     IAM_LOGI("start");
191     std::lock_guard<std::recursive_mutex> lock(mutex_);
192     if (addedToDriver_) {
193         DeleteExecutorFromDriver(executorIndex_);
194     }
195     addedToDriver_ = false;
196 }
197 
DetachFromDriver()198 void ResourceNodeImpl::DetachFromDriver()
199 {
200     IAM_LOGI("start");
201     std::lock_guard<std::recursive_mutex> lock(mutex_);
202     addedToDriver_ = false;
203 }
204 
AddToDriver(std::vector<uint64_t> & templateIdList,std::vector<uint8_t> & fwkPublicKey)205 int32_t ResourceNodeImpl::AddToDriver(std::vector<uint64_t> &templateIdList, std::vector<uint8_t> &fwkPublicKey)
206 {
207     HdiExecutorRegisterInfo hdiInfo = {
208         .authType = static_cast<HdiAuthType>(info_.authType),
209         .executorRole = static_cast<HdiExecutorRole>(info_.executorRole),
210         .executorSensorHint = info_.executorSensorHint,
211         .executorMatcher = info_.executorMatcher,
212         .esl = static_cast<HdiExecutorSecureLevel>(info_.esl),
213         .maxTemplateAcl = info_.maxTemplateAcl,
214         .publicKey = info_.publicKey,
215         .deviceUdid = info_.deviceUdid,
216         .signedRemoteExecutorInfo = info_.signedRemoteExecutorInfo,
217     };
218 
219     auto hdi = HdiWrapper::GetHdiInstance();
220     if (!hdi) {
221         IAM_LOGE("bad hdi");
222         return GENERAL_ERROR;
223     }
224 
225     int32_t result = hdi->AddExecutor(hdiInfo, executorIndex_, fwkPublicKey, templateIdList);
226     if (result != HDF_SUCCESS) {
227         IAM_LOGE("hdi AddExecutor failed with code %{public}d", result);
228         return GENERAL_ERROR;
229     }
230     addedToDriver_ = true;
231     IAM_LOGI("hdi AddExecutor ****%{public}hx success", static_cast<uint16_t>(executorIndex_));
232     return SUCCESS;
233 }
234 
DeleteExecutorFromDriver(uint64_t executorIndex)235 void ResourceNodeImpl::DeleteExecutorFromDriver(uint64_t executorIndex)
236 {
237     auto hdi = HdiWrapper::GetHdiInstance();
238     if (!hdi) {
239         IAM_LOGE("bad hdi");
240         return;
241     }
242 
243     auto result = hdi->DeleteExecutor(executorIndex);
244     if (result != HDF_SUCCESS) {
245         IAM_LOGE("hdi DeleteExecutor ****%{public}hx with %{public}d", static_cast<uint16_t>(executorIndex), result);
246         return;
247     }
248     IAM_LOGI("hdi DeleteExecutor ****%{public}hx success", static_cast<uint16_t>(executorIndex));
249 }
250 
MakeNewResource(const ExecutorRegisterInfo & info,const std::shared_ptr<ExecutorCallbackInterface> & callback,std::vector<uint64_t> & templateIdList,std::vector<uint8_t> & fwkPublicKey)251 std::shared_ptr<ResourceNode> ResourceNode::MakeNewResource(const ExecutorRegisterInfo &info,
252     const std::shared_ptr<ExecutorCallbackInterface> &callback, std::vector<uint64_t> &templateIdList,
253     std::vector<uint8_t> &fwkPublicKey)
254 {
255     auto node = Common::MakeShared<ResourceNodeImpl>(info, callback);
256     if (node == nullptr) {
257         IAM_LOGE("bad alloc");
258         return nullptr;
259     }
260 
261     int32_t result = node->AddToDriver(templateIdList, fwkPublicKey);
262     if (result != 0) {
263         IAM_LOGE("hdi error with %{public}d", result);
264         return nullptr;
265     }
266 
267     return node;
268 }
269 } // namespace UserAuth
270 } // namespace UserIam
271 } // namespace OHOS
272