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