• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 "fingerprint_auth_executor_hdi.h"
17 
18 #include <cstdint>
19 #include <functional>
20 #include <map>
21 #include <memory>
22 #include <new>
23 #include <utility>
24 #include <vector>
25 
26 #include "hdf_base.h"
27 #include "refbase.h"
28 
29 #include "iam_check.h"
30 #include "iam_executor_framework_types.h"
31 #include "iam_logger.h"
32 #include "memory_guard.h"
33 
34 #include "fingerprint_auth_defines.h"
35 #include "fingerprint_auth_executor_callback_hdi.h"
36 #include "fingerprint_auth_hdi.h"
37 #include "sa_command_manager.h"
38 
39 #define LOG_LABEL UserIam::Common::LABEL_FINGERPRINT_AUTH_SA
40 
41 namespace OHOS {
42 namespace UserIam {
43 namespace FingerprintAuth {
44 using IamResultCode = UserAuth::ResultCode;
45 using IamExecutorRole = UserAuth::ExecutorRole;
46 using IamExecutorInfo = UserAuth::ExecutorInfo;
47 namespace UserAuth = OHOS::UserIam::UserAuth;
FingerprintAuthExecutorHdi(sptr<IExecutor> executorProxy)48 FingerprintAuthExecutorHdi::FingerprintAuthExecutorHdi(sptr<IExecutor> executorProxy)
49     : executorProxy_(executorProxy) {};
50 
GetExecutorInfo(IamExecutorInfo & info)51 IamResultCode FingerprintAuthExecutorHdi::GetExecutorInfo(IamExecutorInfo &info)
52 {
53     IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
54     ExecutorInfo localInfo = {};
55     int32_t status = executorProxy_->GetExecutorInfo(localInfo);
56     IamResultCode result = ConvertResultCode(status);
57     if (result != IamResultCode::SUCCESS) {
58         IAM_LOGE("GetExecutorInfo fail result %{public}d", result);
59         return result;
60     }
61     result = MoveHdiExecutorInfo(localInfo, info);
62     if (result != IamResultCode::SUCCESS) {
63         IAM_LOGE("MoveHdiExecutorInfo fail result %{public}d", result);
64         return result;
65     }
66     return IamResultCode::SUCCESS;
67 }
68 
OnRegisterFinish(const std::vector<uint64_t> & templateIdList,const std::vector<uint8_t> & frameworkPublicKey,const std::vector<uint8_t> & extraInfo)69 IamResultCode FingerprintAuthExecutorHdi::OnRegisterFinish(const std::vector<uint64_t> &templateIdList,
70     const std::vector<uint8_t> &frameworkPublicKey, const std::vector<uint8_t> &extraInfo)
71 {
72     IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
73     int32_t status = executorProxy_->OnRegisterFinish(templateIdList, frameworkPublicKey, extraInfo);
74     IamResultCode result = ConvertResultCode(status);
75     if (result != IamResultCode::SUCCESS) {
76         IAM_LOGE("OnRegisterFinish fail result %{public}d", result);
77         return result;
78     }
79 
80     result = RegisterSaCommandCallback();
81     if (result != IamResultCode::SUCCESS) {
82         IAM_LOGE("RegisterSaCommandCallback fail");
83         return result;
84     }
85     return IamResultCode::SUCCESS;
86 }
87 
Enroll(uint64_t scheduleId,const UserAuth::EnrollParam & param,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)88 IamResultCode FingerprintAuthExecutorHdi::Enroll(uint64_t scheduleId, const UserAuth::EnrollParam &param,
89     const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
90 {
91     IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
92     IF_FALSE_LOGE_AND_RETURN_VAL(callbackObj != nullptr, IamResultCode::GENERAL_ERROR);
93     sptr<IExecutorCallback> callback(new (std::nothrow) FingerprintAuthExecutorCallbackHdi(callbackObj));
94     IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, IamResultCode::GENERAL_ERROR);
95     int32_t status = executorProxy_->Enroll(scheduleId, param.extraInfo, callback);
96     IamResultCode result = ConvertResultCode(status);
97     if (result != IamResultCode::SUCCESS) {
98         IAM_LOGE("Enroll fail result %{public}d", result);
99         return result;
100     }
101     return IamResultCode::SUCCESS;
102 }
103 
Authenticate(uint64_t scheduleId,const UserAuth::AuthenticateParam & param,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)104 IamResultCode FingerprintAuthExecutorHdi::Authenticate(uint64_t scheduleId, const UserAuth::AuthenticateParam &param,
105     const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
106 {
107     IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
108     IF_FALSE_LOGE_AND_RETURN_VAL(callbackObj != nullptr, IamResultCode::GENERAL_ERROR);
109     sptr<IExecutorCallback> callback(new (std::nothrow) FingerprintAuthExecutorCallbackHdi(callbackObj));
110     IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, IamResultCode::GENERAL_ERROR);
111     int32_t status = executorProxy_->AuthenticateV1_1(scheduleId, param.templateIdList, param.endAfterFirstFail,
112         param.extraInfo, callback);
113     IamResultCode result = ConvertResultCode(status);
114     if (result != IamResultCode::SUCCESS) {
115         IAM_LOGE("Authenticate fail result %{public}d", result);
116         return result;
117     }
118     return IamResultCode::SUCCESS;
119 }
120 
Identify(uint64_t scheduleId,const UserAuth::IdentifyParam & param,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)121 IamResultCode FingerprintAuthExecutorHdi::Identify(uint64_t scheduleId, const UserAuth::IdentifyParam &param,
122     const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
123 {
124     IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
125     IF_FALSE_LOGE_AND_RETURN_VAL(callbackObj != nullptr, IamResultCode::GENERAL_ERROR);
126     sptr<IExecutorCallback> callback(new (std::nothrow) FingerprintAuthExecutorCallbackHdi(callbackObj));
127     IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, IamResultCode::GENERAL_ERROR);
128     int32_t status = executorProxy_->Identify(scheduleId, param.extraInfo, callback);
129     IamResultCode result = ConvertResultCode(status);
130     if (result != IamResultCode::SUCCESS) {
131         IAM_LOGE("Identify fail result %{public}d", result);
132         return result;
133     }
134     return IamResultCode::SUCCESS;
135 }
136 
Delete(const std::vector<uint64_t> & templateIdList)137 IamResultCode FingerprintAuthExecutorHdi::Delete(const std::vector<uint64_t> &templateIdList)
138 {
139     IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
140     int32_t status = executorProxy_->Delete(templateIdList);
141     IamResultCode result = ConvertResultCode(status);
142     if (result != IamResultCode::SUCCESS) {
143         IAM_LOGE("Delete fail result %{public}d", result);
144         return result;
145     }
146     return IamResultCode::SUCCESS;
147 }
148 
Cancel(uint64_t scheduleId)149 IamResultCode FingerprintAuthExecutorHdi::Cancel(uint64_t scheduleId)
150 {
151     IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
152     int32_t status = executorProxy_->Cancel(scheduleId);
153     IamResultCode result = ConvertResultCode(status);
154     if (result != IamResultCode::SUCCESS) {
155         IAM_LOGE("Cancel fail result %{public}d", result);
156         return result;
157     }
158     return IamResultCode::SUCCESS;
159 }
160 
SendCommand(UserAuth::PropertyMode commandId,const std::vector<uint8_t> & extraInfo,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)161 IamResultCode FingerprintAuthExecutorHdi::SendCommand(UserAuth::PropertyMode commandId,
162     const std::vector<uint8_t> &extraInfo, const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
163 {
164     IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
165     IF_FALSE_LOGE_AND_RETURN_VAL(callbackObj != nullptr, IamResultCode::GENERAL_ERROR);
166     CommandId hdiCommandId;
167     IamResultCode result = ConvertCommandId(commandId, hdiCommandId);
168     if (result != IamResultCode::SUCCESS) {
169         IAM_LOGE("ConvertCommandId fail result %{public}d", result);
170         return result;
171     }
172     sptr<IExecutorCallback> callback(new (std::nothrow) FingerprintAuthExecutorCallbackHdi(callbackObj));
173     IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, IamResultCode::GENERAL_ERROR);
174     int32_t status = executorProxy_->SendCommand(hdiCommandId, extraInfo, callback);
175     result = ConvertResultCode(status);
176     if (result != IamResultCode::SUCCESS) {
177         IAM_LOGE("SendCommand fail result %{public}d", result);
178         return result;
179     }
180     return IamResultCode::SUCCESS;
181 }
182 
GetProperty(const std::vector<uint64_t> & templateIdList,const std::vector<UserAuth::Attributes::AttributeKey> & keys,UserAuth::Property & property)183 UserAuth::ResultCode FingerprintAuthExecutorHdi::GetProperty(const std::vector<uint64_t> &templateIdList,
184     const std::vector<UserAuth::Attributes::AttributeKey> &keys, UserAuth::Property &property)
185 {
186     IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
187 
188     std::vector<GetPropertyType> propertyTypes;
189     IamResultCode result = ConvertAttributeKeyVectorToPropertyType(keys, propertyTypes);
190     IF_FALSE_LOGE_AND_RETURN_VAL(result == IamResultCode::SUCCESS, IamResultCode::GENERAL_ERROR);
191 
192     Property hdiProperty;
193     int32_t status = executorProxy_->GetProperty(templateIdList, propertyTypes, hdiProperty);
194     result = ConvertResultCode(status);
195     if (result != IamResultCode::SUCCESS) {
196         IAM_LOGE("SendCommand fail result %{public}d", result);
197         return result;
198     }
199     MoveHdiProperty(hdiProperty, property);
200     return IamResultCode::SUCCESS;
201 }
202 
SetCachedTemplates(const std::vector<uint64_t> & templateIdList)203 UserAuth::ResultCode FingerprintAuthExecutorHdi::SetCachedTemplates(const std::vector<uint64_t> &templateIdList)
204 {
205     IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
206 
207     int32_t status = executorProxy_->SetCachedTemplates(templateIdList);
208     IamResultCode result = ConvertResultCode(status);
209     if (result != IamResultCode::SUCCESS) {
210         IAM_LOGE("SendCommand fail result %{public}d", result);
211         return result;
212     }
213     return IamResultCode::SUCCESS;
214 }
215 
OnHdiDisconnect()216 void FingerprintAuthExecutorHdi::OnHdiDisconnect()
217 {
218     IAM_LOGE("start");
219     SaCommandManager::GetInstance().OnHdiDisconnect(shared_from_this());
220 }
221 
MoveHdiExecutorInfo(ExecutorInfo & in,IamExecutorInfo & out)222 IamResultCode FingerprintAuthExecutorHdi::MoveHdiExecutorInfo(ExecutorInfo &in, IamExecutorInfo &out)
223 {
224     out.executorSensorHint = static_cast<uint32_t>(in.sensorId);
225     out.executorMatcher = in.executorType;
226     IamResultCode result = ConvertExecutorRole(in.executorRole, out.executorRole);
227     if (result != IamResultCode::SUCCESS) {
228         IAM_LOGE("ConvertExecutorRole fail result %{public}d", result);
229         return result;
230     }
231     result = ConvertAuthType(in.authType, out.authType);
232     if (result != IamResultCode::SUCCESS) {
233         IAM_LOGE("ConvertAuthType fail result %{public}d", result);
234         return result;
235     }
236     result = ConvertExecutorSecureLevel(in.esl, out.esl);
237     if (result != IamResultCode::SUCCESS) {
238         IAM_LOGE("ConvertExecutorSecureLevel fail result %{public}d", result);
239         return result;
240     }
241     in.publicKey.swap(out.publicKey);
242     return IamResultCode::SUCCESS;
243 }
244 
MoveHdiProperty(Property & in,UserAuth::Property & out)245 void FingerprintAuthExecutorHdi::MoveHdiProperty(Property &in, UserAuth::Property &out)
246 {
247     out.authSubType = in.authSubType;
248     out.lockoutDuration = in.lockoutDuration;
249     out.remainAttempts = in.remainAttempts;
250     out.enrollmentProgress.swap(in.enrollmentProgress);
251     out.sensorInfo.swap(in.sensorInfo);
252 }
253 
MoveHdiTemplateInfo(TemplateInfo & in,UserAuth::TemplateInfo & out)254 void FingerprintAuthExecutorHdi::MoveHdiTemplateInfo(TemplateInfo &in, UserAuth::TemplateInfo &out)
255 {
256     out.executorType = in.executorType;
257     out.freezingTime = in.lockoutDuration;
258     out.remainTimes = in.remainAttempts;
259     in.extraInfo.swap(out.extraInfo);
260 }
261 
ConvertCommandId(const UserAuth::PropertyMode in,CommandId & out)262 IamResultCode FingerprintAuthExecutorHdi::ConvertCommandId(const UserAuth::PropertyMode in, CommandId &out)
263 {
264     if (static_cast<CommandId>(in) > CommandId::VENDOR_COMMAND_BEGIN) {
265         out = static_cast<CommandId>(in);
266         IAM_LOGI("vendor command id %{public}d, no covert", out);
267         return IamResultCode::SUCCESS;
268     }
269 
270     static const std::map<UserAuth::PropertyMode, CommandId> data = {
271         { UserAuth::PropertyMode::PROPERTY_INIT_ALGORITHM, CommandId::INIT_ALGORITHM },
272         { UserAuth::PropertyMode::PROPERTY_MODE_FREEZE, CommandId::LOCK_TEMPLATE },
273         { UserAuth::PropertyMode::PROPERTY_MODE_UNFREEZE, CommandId::UNLOCK_TEMPLATE } };
274     auto iter = data.find(in);
275     if (iter == data.end()) {
276         IAM_LOGE("command id %{public}d is invalid", in);
277         return IamResultCode::INVALID_PARAMETERS;
278     }
279     out = iter->second;
280     IAM_LOGI("covert command id %{public}d to idl command is %{public}d", in, out);
281     return IamResultCode::SUCCESS;
282 }
283 
ConvertAuthType(const AuthType in,UserAuth::AuthType & out)284 IamResultCode FingerprintAuthExecutorHdi::ConvertAuthType(const AuthType in, UserAuth::AuthType &out)
285 {
286     static const std::map<AuthType, UserAuth::AuthType> data = {
287         { AuthType::FINGERPRINT, UserAuth::AuthType::FINGERPRINT },
288     };
289     auto iter = data.find(in);
290     if (iter == data.end()) {
291         IAM_LOGE("authType %{public}d is invalid", in);
292         return IamResultCode::GENERAL_ERROR;
293     }
294     out = iter->second;
295     return IamResultCode::SUCCESS;
296 }
297 
ConvertExecutorRole(const ExecutorRole in,IamExecutorRole & out)298 IamResultCode FingerprintAuthExecutorHdi::ConvertExecutorRole(const ExecutorRole in, IamExecutorRole &out)
299 {
300     static const std::map<ExecutorRole, IamExecutorRole> data = {
301         { ExecutorRole::COLLECTOR, IamExecutorRole::COLLECTOR },
302         { ExecutorRole::VERIFIER, IamExecutorRole::VERIFIER },
303         { ExecutorRole::ALL_IN_ONE, IamExecutorRole::ALL_IN_ONE },
304     };
305     auto iter = data.find(in);
306     if (iter == data.end()) {
307         IAM_LOGE("executorRole %{public}d is invalid", in);
308         return IamResultCode::GENERAL_ERROR;
309     }
310     out = iter->second;
311     return IamResultCode::SUCCESS;
312 }
313 
ConvertExecutorSecureLevel(const ExecutorSecureLevel in,UserAuth::ExecutorSecureLevel & out)314 IamResultCode FingerprintAuthExecutorHdi::ConvertExecutorSecureLevel(const ExecutorSecureLevel in,
315     UserAuth::ExecutorSecureLevel &out)
316 {
317     static const std::map<ExecutorSecureLevel, UserAuth::ExecutorSecureLevel> data = {
318         { ExecutorSecureLevel::ESL0, UserAuth::ExecutorSecureLevel::ESL0 },
319         { ExecutorSecureLevel::ESL1, UserAuth::ExecutorSecureLevel::ESL1 },
320         { ExecutorSecureLevel::ESL2, UserAuth::ExecutorSecureLevel::ESL2 },
321         { ExecutorSecureLevel::ESL3, UserAuth::ExecutorSecureLevel::ESL3 },
322     };
323     auto iter = data.find(in);
324     if (iter == data.end()) {
325         IAM_LOGE("executorSecureLevel %{public}d is invalid", in);
326         return IamResultCode::GENERAL_ERROR;
327     }
328     out = iter->second;
329     return IamResultCode::SUCCESS;
330 }
331 
ConvertResultCode(const int32_t in)332 IamResultCode FingerprintAuthExecutorHdi::ConvertResultCode(const int32_t in)
333 {
334     HDF_STATUS hdfIn = static_cast<HDF_STATUS>(in);
335     static const std::map<HDF_STATUS, IamResultCode> data = {
336         { HDF_SUCCESS, IamResultCode::SUCCESS },
337         { HDF_FAILURE, IamResultCode::GENERAL_ERROR },
338         { HDF_ERR_TIMEOUT, IamResultCode::TIMEOUT },
339         { HDF_ERR_QUEUE_FULL, IamResultCode::BUSY },
340         { HDF_ERR_DEVICE_BUSY, IamResultCode::BUSY },
341     };
342 
343     IamResultCode out;
344     auto iter = data.find(hdfIn);
345     if (iter == data.end()) {
346         out = IamResultCode::GENERAL_ERROR;
347     } else {
348         out = iter->second;
349     }
350     IAM_LOGI("covert hdi result code %{public}d to framework result code %{public}d", in, out);
351     return out;
352 }
353 
ConvertAttributeKeyVectorToPropertyType(const std::vector<UserAuth::Attributes::AttributeKey> inItems,std::vector<GetPropertyType> & outItems)354 IamResultCode FingerprintAuthExecutorHdi::ConvertAttributeKeyVectorToPropertyType(
355     const std::vector<UserAuth::Attributes::AttributeKey> inItems, std::vector<GetPropertyType> &outItems)
356 {
357     outItems.clear();
358     for (auto &inItem : inItems) {
359         GetPropertyType outItem;
360         IamResultCode result = ConvertAttributeKeyToPropertyType(inItem, outItem);
361         IF_FALSE_LOGE_AND_RETURN_VAL(result == IamResultCode::SUCCESS, IamResultCode::GENERAL_ERROR);
362         outItems.push_back(outItem);
363     }
364 
365     return IamResultCode::SUCCESS;
366 }
367 
ConvertAttributeKeyToPropertyType(const UserAuth::Attributes::AttributeKey in,GetPropertyType & out)368 IamResultCode FingerprintAuthExecutorHdi::ConvertAttributeKeyToPropertyType(const UserAuth::Attributes::AttributeKey in,
369     GetPropertyType &out)
370 {
371     static const std::map<UserAuth::Attributes::AttributeKey, GetPropertyType> data = {
372         { UserAuth::Attributes::ATTR_PIN_SUB_TYPE, GetPropertyType::AUTH_SUB_TYPE },
373         { UserAuth::Attributes::ATTR_FREEZING_TIME, GetPropertyType::LOCKOUT_DURATION },
374         { UserAuth::Attributes::ATTR_REMAIN_TIMES, GetPropertyType::REMAIN_ATTEMPTS },
375         { UserAuth::Attributes::ATTR_ENROLL_PROGRESS, GetPropertyType::ENROLL_PROGRESS },
376         { UserAuth::Attributes::ATTR_SENSOR_INFO, GetPropertyType::SENSOR_INFO },
377     };
378 
379     auto iter = data.find(in);
380     if (iter == data.end()) {
381         IAM_LOGE("attribute %{public}d is invalid", in);
382         return IamResultCode::GENERAL_ERROR;
383     } else {
384         out = iter->second;
385     }
386     IAM_LOGI("covert hdi result code %{public}d to framework result code %{public}d", in, out);
387     return IamResultCode::SUCCESS;
388 }
389 
RegisterSaCommandCallback()390 UserAuth::ResultCode FingerprintAuthExecutorHdi::RegisterSaCommandCallback()
391 {
392     sptr<SaCommandCallback> callback(new (std::nothrow) SaCommandCallback(shared_from_this()));
393     IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, IamResultCode::GENERAL_ERROR);
394 
395     int32_t status = executorProxy_->RegisterSaCommandCallback(callback);
396     IamResultCode result = ConvertResultCode(status);
397     if (result != IamResultCode::SUCCESS) {
398         IAM_LOGE("RegisterSaCommandCallback fail result %{public}d", result);
399         return result;
400     }
401 
402     return IamResultCode::SUCCESS;
403 }
404 
OnSaCommands(const std::vector<SaCommand> & commands)405 int32_t FingerprintAuthExecutorHdi::SaCommandCallback::OnSaCommands(const std::vector<SaCommand> &commands)
406 {
407     IAM_LOGI("start");
408     MemoryGuard guard;
409     IamResultCode result = SaCommandManager::GetInstance().ProcessSaCommands(executorHdi_, commands);
410     if (result != IamResultCode::SUCCESS) {
411         IAM_LOGE("ProcessSaCommands fail");
412         return HDF_FAILURE;
413     }
414     IAM_LOGI("success");
415     return HDF_SUCCESS;
416 };
417 } // namespace FingerprintAuth
418 } // namespace UserIam
419 } // namespace OHOS
420