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 ¶m,
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 ¶m,
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 ¶m,
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