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