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 "pin_auth_executor_hdi.h"
17
18 #include "hdf_base.h"
19 #include "hisysevent.h"
20
21 #include "iam_check.h"
22 #include "iam_defines.h"
23 #include "iam_logger.h"
24 #include "pin_auth_executor_callback_hdi.h"
25
26 #define LOG_LABEL UserIam::Common::LABEL_PIN_AUTH_SA
27
28 namespace OHOS {
29 namespace UserIam {
30 namespace PinAuth {
31 using IamResultCode = OHOS::UserIam::UserAuth::ResultCode;
32 using IamExecutorRole = UserIam::UserAuth::ExecutorRole;
33
PinAuthExecutorHdi(const sptr<HDI::PinAuth::V1_1::IExecutor> & executorProxy)34 PinAuthExecutorHdi::PinAuthExecutorHdi(const sptr<HDI::PinAuth::V1_1::IExecutor> &executorProxy)
35 : executorProxy_(executorProxy)
36 {
37 }
38
GetExecutorInfo(UserAuth::ExecutorInfo & info)39 IamResultCode PinAuthExecutorHdi::GetExecutorInfo(UserAuth::ExecutorInfo &info)
40 {
41 if (executorProxy_ == nullptr) {
42 IAM_LOGE("executorProxy is null");
43 return IamResultCode::GENERAL_ERROR;
44 }
45
46 ExecutorInfo localInfo = { };
47 int32_t status = executorProxy_->GetExecutorInfo(localInfo);
48 IamResultCode result = ConvertResultCode(status);
49 if (result != IamResultCode::SUCCESS) {
50 IAM_LOGE("GetExecutorInfo fail ret=%{public}d", result);
51 return result;
52 }
53 int32_t ret = MoveHdiExecutorInfo(localInfo, info);
54 if (ret != IamResultCode::SUCCESS) {
55 IAM_LOGE("MoveHdiExecutorInfo fail ret=%{public}d", ret);
56 return IamResultCode::GENERAL_ERROR;
57 }
58 return IamResultCode::SUCCESS;
59 }
60
OnRegisterFinish(const std::vector<uint64_t> & templateIdList,const std::vector<uint8_t> & frameworkPublicKey,const std::vector<uint8_t> & extraInfo)61 IamResultCode PinAuthExecutorHdi::OnRegisterFinish(const std::vector<uint64_t> &templateIdList,
62 const std::vector<uint8_t> &frameworkPublicKey, const std::vector<uint8_t> &extraInfo)
63 {
64 if (executorProxy_ == nullptr) {
65 IAM_LOGE("executorProxy is null");
66 return IamResultCode::GENERAL_ERROR;
67 }
68 int32_t status = executorProxy_->OnRegisterFinish(templateIdList, frameworkPublicKey, extraInfo);
69 IamResultCode result = ConvertResultCode(status);
70 if (result != IamResultCode::SUCCESS) {
71 IAM_LOGE("OnRegisterFinish fail result %{public}d", result);
72 return result;
73 }
74
75 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::USERIAM_PIN, "USERIAM_TEMPLATE_CHANGE",
76 OHOS::HiviewDFX::HiSysEvent::EventType::SECURITY, "EXECUTOR_TYPE", UserAuth::PIN,
77 "CHANGE_TYPE", UserAuth::TRACE_DELETE_CREDENTIAL, "TRIGGER_REASON", "Reconciliation");
78 return IamResultCode::SUCCESS;
79 }
80
OnSetData(uint64_t scheduleId,uint64_t authSubType,const std::vector<uint8_t> & data)81 IamResultCode PinAuthExecutorHdi::OnSetData(uint64_t scheduleId, uint64_t authSubType,
82 const std::vector<uint8_t> &data)
83 {
84 if (executorProxy_ == nullptr) {
85 IAM_LOGE("executorProxy is null");
86 return IamResultCode::GENERAL_ERROR;
87 }
88 int32_t status = executorProxy_->OnSetData(scheduleId, authSubType, data);
89 IamResultCode result = ConvertResultCode(status);
90 if (result != IamResultCode::SUCCESS) {
91 IAM_LOGE("OnRegisterFinish fail ret=%{public}d", result);
92 return result;
93 }
94 return IamResultCode::SUCCESS;
95 }
96
Enroll(uint64_t scheduleId,const UserAuth::EnrollParam & param,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)97 IamResultCode PinAuthExecutorHdi::Enroll(uint64_t scheduleId, const UserAuth::EnrollParam ¶m,
98 const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
99 {
100 if (executorProxy_ == nullptr) {
101 IAM_LOGE("executorProxy is null");
102 return IamResultCode::GENERAL_ERROR;
103 }
104 if (callbackObj == nullptr) {
105 IAM_LOGE("callbackObj is null");
106 return IamResultCode::GENERAL_ERROR;
107 }
108 auto callback = sptr<IExecutorCallback>(
109 new (std::nothrow) PinAuthExecutorCallbackHdi(callbackObj, shared_from_this(), param.tokenId, true));
110 if (callback == nullptr) {
111 IAM_LOGE("callback is null");
112 return IamResultCode::GENERAL_ERROR;
113 }
114 int32_t status = executorProxy_->EnrollV1_1(scheduleId, param.extraInfo, callback);
115 IamResultCode result = ConvertResultCode(status);
116 if (result != IamResultCode::SUCCESS) {
117 IAM_LOGE("Enroll fail ret=%{public}d", result);
118 return result;
119 }
120 return IamResultCode::SUCCESS;
121 }
122
Authenticate(uint64_t scheduleId,const UserAuth::AuthenticateParam & param,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)123 IamResultCode PinAuthExecutorHdi::Authenticate(uint64_t scheduleId, const UserAuth::AuthenticateParam ¶m,
124 const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
125 {
126 if (executorProxy_ == nullptr) {
127 IAM_LOGE("executorProxy is null");
128 return IamResultCode::GENERAL_ERROR;
129 }
130 if (callbackObj == nullptr) {
131 IAM_LOGE("callbackObj is null");
132 return IamResultCode::GENERAL_ERROR;
133 }
134 auto callback = sptr<IExecutorCallback>(
135 new (std::nothrow) PinAuthExecutorCallbackHdi(callbackObj, shared_from_this(), param.tokenId, false));
136 if (callback == nullptr) {
137 IAM_LOGE("callback is null");
138 return IamResultCode::GENERAL_ERROR;
139 }
140 if (param.templateIdList.size() == 0) {
141 IAM_LOGE("Error param");
142 return IamResultCode::GENERAL_ERROR;
143 }
144 int32_t status = executorProxy_->AuthenticateV1_1(scheduleId, param.templateIdList[0], param.extraInfo, callback);
145 IamResultCode result = ConvertResultCode(status);
146 if (result != IamResultCode::SUCCESS) {
147 IAM_LOGE("Authenticate fail ret=%{public}d", result);
148 return result;
149 }
150 return IamResultCode::SUCCESS;
151 }
152
Identify(uint64_t scheduleId,const UserAuth::IdentifyParam & param,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)153 IamResultCode PinAuthExecutorHdi::Identify(uint64_t scheduleId, const UserAuth::IdentifyParam ¶m,
154 const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
155 {
156 IAM_LOGI("Adaptor frame interface, temporarily useless");
157 static_cast<void>(scheduleId);
158 static_cast<void>(param);
159 static_cast<void>(callbackObj);
160 return IamResultCode::SUCCESS;
161 }
162
Delete(const std::vector<uint64_t> & templateIdList)163 IamResultCode PinAuthExecutorHdi::Delete(const std::vector<uint64_t> &templateIdList)
164 {
165 if (executorProxy_ == nullptr) {
166 IAM_LOGE("executorProxy is null");
167 return IamResultCode::GENERAL_ERROR;
168 }
169 int32_t status = executorProxy_->Delete(templateIdList[0]);
170 IamResultCode result = ConvertResultCode(status);
171 if (result != IamResultCode::SUCCESS) {
172 IAM_LOGE("Delete fail ret=%{public}d", result);
173 return result;
174 }
175 return IamResultCode::SUCCESS;
176 }
177
Cancel(uint64_t scheduleId)178 IamResultCode PinAuthExecutorHdi::Cancel(uint64_t scheduleId)
179 {
180 if (executorProxy_ == nullptr) {
181 IAM_LOGE("executorProxy is null");
182 return IamResultCode::GENERAL_ERROR;
183 }
184 int32_t status = executorProxy_->Cancel(scheduleId);
185 IamResultCode result = ConvertResultCode(status);
186 if (result != IamResultCode::SUCCESS) {
187 IAM_LOGE("Cancel fail ret=%{public}d", result);
188 return result;
189 }
190 return IamResultCode::SUCCESS;
191 }
192
SendCommand(UserAuth::PropertyMode commandId,const std::vector<uint8_t> & extraInfo,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)193 IamResultCode PinAuthExecutorHdi::SendCommand(UserAuth::PropertyMode commandId, const std::vector<uint8_t> &extraInfo,
194 const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
195 {
196 IAM_LOGI("Adaptor frame interface, temporarily useless");
197 static_cast<void>(commandId);
198 static_cast<void>(extraInfo);
199 static_cast<void>(callbackObj);
200 return IamResultCode::SUCCESS;
201 }
202
GetProperty(const std::vector<uint64_t> & templateIdList,const std::vector<UserAuth::Attributes::AttributeKey> & keys,UserAuth::Property & property)203 UserAuth::ResultCode PinAuthExecutorHdi::GetProperty(const std::vector<uint64_t> &templateIdList,
204 const std::vector<UserAuth::Attributes::AttributeKey> &keys, UserAuth::Property &property)
205 {
206 IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
207
208 std::vector<GetPropertyType> propertyTypes;
209 IamResultCode result = ConvertAttributeKeyVectorToPropertyType(keys, propertyTypes);
210 IF_FALSE_LOGE_AND_RETURN_VAL(result == IamResultCode::SUCCESS, IamResultCode::GENERAL_ERROR);
211
212 Property hdiProperty;
213 int32_t status = executorProxy_->GetProperty(templateIdList, propertyTypes, hdiProperty);
214 result = ConvertResultCode(status);
215 if (result != IamResultCode::SUCCESS) {
216 IAM_LOGE("SendCommand fail result %{public}d", result);
217 return result;
218 }
219 MoveHdiProperty(hdiProperty, property);
220 return IamResultCode::SUCCESS;
221 }
222
SetCachedTemplates(const std::vector<uint64_t> & templateIdList)223 UserAuth::ResultCode PinAuthExecutorHdi::SetCachedTemplates(const std::vector<uint64_t> &templateIdList)
224 {
225 static_cast<void>(templateIdList);
226 IAM_LOGI("SetCachedTemplates is not supported");
227 return IamResultCode::SUCCESS;
228 }
229
MoveHdiExecutorInfo(ExecutorInfo & in,UserAuth::ExecutorInfo & out)230 IamResultCode PinAuthExecutorHdi::MoveHdiExecutorInfo(ExecutorInfo &in, UserAuth::ExecutorInfo &out)
231 {
232 out.executorSensorHint = static_cast<uint32_t>(in.sensorId);
233 out.executorMatcher = in.executorType;
234 int32_t ret = ConvertExecutorRole(in.executorRole, out.executorRole);
235 if (ret != IamResultCode::SUCCESS) {
236 IAM_LOGE("executorProxy is null");
237 return IamResultCode::GENERAL_ERROR;
238 }
239 ret = ConvertAuthType(in.authType, out.authType);
240 if (ret != IamResultCode::SUCCESS) {
241 IAM_LOGE("ConvertAuthType fail ret=%{public}d", ret);
242 return IamResultCode::GENERAL_ERROR;
243 }
244 ret = ConvertExecutorSecureLevel(in.esl, out.esl);
245 if (ret != IamResultCode::SUCCESS) {
246 IAM_LOGE("ConvertExecutorSecureLevel fail ret=%{public}d", ret);
247 return IamResultCode::GENERAL_ERROR;
248 }
249 in.publicKey.swap(out.publicKey);
250 return IamResultCode::SUCCESS;
251 }
252
MoveHdiTemplateInfo(TemplateInfo & in,UserAuth::TemplateInfo & out)253 IamResultCode PinAuthExecutorHdi::MoveHdiTemplateInfo(TemplateInfo &in, UserAuth::TemplateInfo &out)
254 {
255 out.executorType = in.executorType;
256 out.freezingTime = in.lockoutDuration;
257 out.remainTimes = in.remainAttempts;
258 in.extraInfo.swap(out.extraInfo);
259 return IamResultCode::SUCCESS;
260 }
261
MoveHdiProperty(Property & in,UserAuth::Property & out)262 void PinAuthExecutorHdi::MoveHdiProperty(Property &in, UserAuth::Property &out)
263 {
264 out.authSubType = in.authSubType;
265 out.lockoutDuration = in.lockoutDuration;
266 out.remainAttempts = in.remainAttempts;
267 }
268
ConvertCommandId(const UserAuth::PropertyMode in,CommandId & out)269 IamResultCode PinAuthExecutorHdi::ConvertCommandId(const UserAuth::PropertyMode in, CommandId &out)
270 {
271 IAM_LOGI("Adaptor frame interface, temporarily useless");
272 static_cast<void>(in);
273 static_cast<void>(out);
274 return IamResultCode::SUCCESS;
275 }
276
ConvertAuthType(const AuthType in,UserAuth::AuthType & out)277 IamResultCode PinAuthExecutorHdi::ConvertAuthType(const AuthType in, UserAuth::AuthType &out)
278 {
279 static const std::map<AuthType, UserAuth::AuthType> data = {
280 {AuthType::PIN, UserAuth::AuthType::PIN},
281 };
282 if (data.count(in) == 0) {
283 IAM_LOGE("authType %{public}d is invalid", in);
284 return IamResultCode::GENERAL_ERROR;
285 }
286 out = data.at(in);
287 return IamResultCode::SUCCESS;
288 }
289
ConvertExecutorRole(const ExecutorRole in,IamExecutorRole & out)290 IamResultCode PinAuthExecutorHdi::ConvertExecutorRole(const ExecutorRole in, IamExecutorRole &out)
291 {
292 static const std::map<ExecutorRole, IamExecutorRole> data = {
293 { ExecutorRole::COLLECTOR, IamExecutorRole::COLLECTOR },
294 { ExecutorRole::VERIFIER, IamExecutorRole::VERIFIER },
295 { ExecutorRole::ALL_IN_ONE, IamExecutorRole::ALL_IN_ONE},
296 };
297 if (data.count(in) == 0) {
298 IAM_LOGE("executorRole %{public}d is invalid", in);
299 return IamResultCode::GENERAL_ERROR;
300 }
301 out = data.at(in);
302 return IamResultCode::SUCCESS;
303 }
304
ConvertExecutorSecureLevel(const ExecutorSecureLevel in,UserAuth::ExecutorSecureLevel & out)305 IamResultCode PinAuthExecutorHdi::ConvertExecutorSecureLevel(const ExecutorSecureLevel in,
306 UserAuth::ExecutorSecureLevel &out)
307 {
308 static const std::map<ExecutorSecureLevel, UserAuth::ExecutorSecureLevel> data = {
309 { ExecutorSecureLevel::ESL0, UserAuth::ExecutorSecureLevel::ESL0 },
310 { ExecutorSecureLevel::ESL1, UserAuth::ExecutorSecureLevel::ESL1 },
311 { ExecutorSecureLevel::ESL2, UserAuth::ExecutorSecureLevel::ESL2 },
312 { ExecutorSecureLevel::ESL3, UserAuth::ExecutorSecureLevel::ESL3 },
313 };
314 if (data.count(in) == 0) {
315 IAM_LOGE("executorSecureLevel %{public}d is invalid", in);
316 return IamResultCode::GENERAL_ERROR;
317 }
318 out = data.at(in);
319 return IamResultCode::SUCCESS;
320 }
321
ConvertResultCode(const int32_t in)322 IamResultCode PinAuthExecutorHdi::ConvertResultCode(const int32_t in)
323 {
324 HDF_STATUS hdfIn = static_cast<HDF_STATUS>(in);
325 static const std::map<HDF_STATUS, IamResultCode> data = {
326 {HDF_SUCCESS, IamResultCode::SUCCESS},
327 {HDF_FAILURE, IamResultCode::FAIL},
328 {HDF_ERR_TIMEOUT, IamResultCode::TIMEOUT},
329 {HDF_ERR_QUEUE_FULL, IamResultCode::BUSY},
330 {HDF_ERR_DEVICE_BUSY, IamResultCode::BUSY},
331 {HDF_ERR_INVALID_PARAM, IamResultCode::INVALID_PARAMETERS},
332 };
333
334 IamResultCode out;
335 if (data.count(hdfIn) == 0) {
336 out = IamResultCode::GENERAL_ERROR;
337 } else {
338 out = data.at(hdfIn);
339 }
340 IAM_LOGI("covert hdi result code %{public}d to framework result code %{public}d", in, out);
341 return out;
342 }
343
ConvertAttributeKeyVectorToPropertyType(const std::vector<UserAuth::Attributes::AttributeKey> inItems,std::vector<GetPropertyType> & outItems)344 IamResultCode PinAuthExecutorHdi::ConvertAttributeKeyVectorToPropertyType(
345 const std::vector<UserAuth::Attributes::AttributeKey> inItems, std::vector<GetPropertyType> &outItems)
346 {
347 outItems.clear();
348 for (auto &inItem : inItems) {
349 if (inItem == UserAuth::Attributes::ATTR_ENROLL_PROGRESS ||
350 inItem == UserAuth::Attributes::ATTR_SENSOR_INFO) {
351 continue;
352 }
353 GetPropertyType outItem;
354 IamResultCode result = ConvertAttributeKeyToPropertyType(inItem, outItem);
355 IF_FALSE_LOGE_AND_RETURN_VAL(result == IamResultCode::SUCCESS, IamResultCode::GENERAL_ERROR);
356 outItems.push_back(outItem);
357 }
358
359 return IamResultCode::SUCCESS;
360 }
361
ConvertAttributeKeyToPropertyType(const UserAuth::Attributes::AttributeKey in,GetPropertyType & out)362 IamResultCode PinAuthExecutorHdi::ConvertAttributeKeyToPropertyType(const UserAuth::Attributes::AttributeKey in,
363 GetPropertyType &out)
364 {
365 static const std::map<UserAuth::Attributes::AttributeKey, GetPropertyType> data = {
366 { UserAuth::Attributes::ATTR_PIN_SUB_TYPE, GetPropertyType::AUTH_SUB_TYPE },
367 { UserAuth::Attributes::ATTR_FREEZING_TIME, GetPropertyType::LOCKOUT_DURATION },
368 { UserAuth::Attributes::ATTR_REMAIN_TIMES, GetPropertyType::REMAIN_ATTEMPTS },
369 };
370
371 auto iter = data.find(in);
372 if (iter == data.end()) {
373 IAM_LOGE("attribute %{public}d is invalid", in);
374 return IamResultCode::GENERAL_ERROR;
375 } else {
376 out = iter->second;
377 }
378 IAM_LOGI("covert hdi result code %{public}d to framework result code %{public}d", in, out);
379 return IamResultCode::SUCCESS;
380 }
381 } // namespace PinAuth
382 } // namespace UserIam
383 } // namespace OHOS
384