1 /*
2 * Copyright (c) 2022-2024 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_all_in_one_hdi.h"
17
18 #include <map>
19
20 #include "hdf_base.h"
21
22 #include "iam_check.h"
23 #include "iam_defines.h"
24 #include "iam_logger.h"
25 #include "pin_auth_executor_callback_hdi.h"
26 #include "pin_auth_executor_hdi_common.h"
27
28 #define LOG_TAG "PIN_AUTH_SA"
29
30 namespace OHOS {
31 namespace UserIam {
32 namespace PinAuth {
PinAuthAllInOneHdi(const sptr<IAllInOneExecutor> & allInOneProxy)33 PinAuthAllInOneHdi::PinAuthAllInOneHdi(const sptr<IAllInOneExecutor> &allInOneProxy)
34 : allInOneProxy_(allInOneProxy)
35 {
36 }
37
GetExecutorInfo(UserAuth::ExecutorInfo & info)38 UserAuth::ResultCode PinAuthAllInOneHdi::GetExecutorInfo(UserAuth::ExecutorInfo &info)
39 {
40 if (allInOneProxy_ == nullptr) {
41 IAM_LOGE("allInOneProxy is null");
42 return UserAuth::ResultCode::GENERAL_ERROR;
43 }
44
45 ExecutorInfo localInfo = { };
46 int32_t status = allInOneProxy_->GetExecutorInfo(localInfo);
47 UserAuth::ResultCode result = ConvertHdiResultCode(status);
48 if (result != UserAuth::ResultCode::SUCCESS) {
49 IAM_LOGE("GetExecutorInfo fail ret=%{public}d", result);
50 return result;
51 }
52 SetAuthType(localInfo.authType);
53 int32_t ret = MoveHdiExecutorInfo(localInfo, info);
54 if (ret != UserAuth::ResultCode::SUCCESS) {
55 IAM_LOGE("MoveHdiExecutorInfo fail ret=%{public}d", ret);
56 return UserAuth::ResultCode::GENERAL_ERROR;
57 }
58 return UserAuth::ResultCode::SUCCESS;
59 }
60
OnRegisterFinish(const std::vector<uint64_t> & templateIdList,const std::vector<uint8_t> & frameworkPublicKey,const std::vector<uint8_t> & extraInfo)61 UserAuth::ResultCode PinAuthAllInOneHdi::OnRegisterFinish(const std::vector<uint64_t> &templateIdList,
62 const std::vector<uint8_t> &frameworkPublicKey, const std::vector<uint8_t> &extraInfo)
63 {
64 if (allInOneProxy_ == nullptr) {
65 IAM_LOGE("allInOneProxy is null");
66 return UserAuth::ResultCode::GENERAL_ERROR;
67 }
68 int32_t status = allInOneProxy_->OnRegisterFinish(templateIdList, frameworkPublicKey, extraInfo);
69 UserAuth::ResultCode result = ConvertHdiResultCode(status);
70 if (result != UserAuth::ResultCode::SUCCESS) {
71 IAM_LOGE("OnRegisterFinish fail result %{public}d", result);
72 return result;
73 }
74
75 return UserAuth::ResultCode::SUCCESS;
76 }
77
SendMessage(uint64_t scheduleId,int32_t srcRole,const std::vector<uint8_t> & msg)78 UserAuth::ResultCode PinAuthAllInOneHdi::SendMessage(
79 uint64_t scheduleId, int32_t srcRole, const std::vector<uint8_t> &msg)
80 {
81 if (allInOneProxy_ == nullptr) {
82 IAM_LOGE("allInOneProxy is null");
83 return UserAuth::ResultCode::GENERAL_ERROR;
84 }
85 int32_t status = allInOneProxy_->SendMessage(scheduleId, srcRole, msg);
86 UserAuth::ResultCode result = ConvertHdiResultCode(status);
87 if (result != UserAuth::ResultCode::SUCCESS) {
88 IAM_LOGE("SendMessage fail result %{public}d", result);
89 return result;
90 }
91 return UserAuth::ResultCode::SUCCESS;
92 }
93
OnSetData(uint64_t scheduleId,uint64_t authSubType,const std::vector<uint8_t> & data,uint32_t pinLength,int32_t errorCode)94 UserAuth::ResultCode PinAuthAllInOneHdi::OnSetData(uint64_t scheduleId, uint64_t authSubType,
95 const std::vector<uint8_t> &data, uint32_t pinLength, int32_t errorCode)
96 {
97 if (allInOneProxy_ == nullptr) {
98 IAM_LOGE("allInOneProxy is null");
99 return UserAuth::ResultCode::GENERAL_ERROR;
100 }
101 int32_t status = allInOneProxy_->SetData(scheduleId, authSubType, data, pinLength, errorCode);
102 UserAuth::ResultCode result = ConvertHdiResultCode(status);
103 if (result != UserAuth::ResultCode::SUCCESS) {
104 IAM_LOGE("OnSetData fail ret=%{public}d", result);
105 return result;
106 }
107 return UserAuth::ResultCode::SUCCESS;
108 }
109
Enroll(uint64_t scheduleId,const UserAuth::EnrollParam & param,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)110 UserAuth::ResultCode PinAuthAllInOneHdi::Enroll(uint64_t scheduleId, const UserAuth::EnrollParam ¶m,
111 const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
112 {
113 if (allInOneProxy_ == nullptr) {
114 IAM_LOGE("allInOneProxy is null");
115 return UserAuth::ResultCode::GENERAL_ERROR;
116 }
117 if (callbackObj == nullptr) {
118 IAM_LOGE("callbackObj is null");
119 return UserAuth::ResultCode::GENERAL_ERROR;
120 }
121 if (!GetAuthType().has_value()) {
122 IAM_LOGE("authType is error");
123 return UserAuth::ResultCode::GENERAL_ERROR;
124 }
125 GetDataMode mode = GET_DATA_MODE_NONE;
126 if (GetAuthType().value() == AuthType::PIN) {
127 mode = GET_DATA_MODE_ALL_IN_ONE_PIN_ENROLL;
128 } else if (GetAuthType().value() == AuthType::PRIVATE_PIN) {
129 mode = GET_DATA_MODE_ALL_IN_ONE_PRIVATE_PIN_ENROLL;
130 } else {
131 mode = GET_DATA_MODE_ALL_IN_ONE_RECOVERY_KEY_ENROLL;
132 }
133 UserAuth::ExecutorParam executorParam = {
134 .tokenId = param.tokenId,
135 .scheduleId = scheduleId,
136 .userId = param.userId,
137 };
138 auto callback = sptr<IExecutorCallback>(new (std::nothrow) PinAuthExecutorCallbackHdi(callbackObj,
139 shared_from_this(), executorParam, mode));
140 if (callback == nullptr) {
141 IAM_LOGE("callback is null");
142 return UserAuth::ResultCode::GENERAL_ERROR;
143 }
144 int32_t status = allInOneProxy_->Enroll(scheduleId, param.extraInfo, callback);
145 UserAuth::ResultCode result = ConvertHdiResultCode(status);
146 if (result != UserAuth::ResultCode::SUCCESS) {
147 IAM_LOGE("Enroll fail ret=%{public}d", result);
148 return result;
149 }
150 return UserAuth::ResultCode::SUCCESS;
151 }
152
Authenticate(uint64_t scheduleId,const UserAuth::AuthenticateParam & param,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)153 UserAuth::ResultCode PinAuthAllInOneHdi::Authenticate(
154 uint64_t scheduleId, const UserAuth::AuthenticateParam ¶m,
155 const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
156 {
157 if (allInOneProxy_ == nullptr) {
158 IAM_LOGE("allInOneProxy is null");
159 return UserAuth::ResultCode::GENERAL_ERROR;
160 }
161 if (callbackObj == nullptr) {
162 IAM_LOGE("callbackObj is null");
163 return UserAuth::ResultCode::GENERAL_ERROR;
164 }
165 if (!GetAuthType().has_value()) {
166 IAM_LOGE("authType is error");
167 return UserAuth::ResultCode::GENERAL_ERROR;
168 }
169 GetDataMode mode = GET_DATA_MODE_NONE;
170 if (GetAuthType().value() == AuthType::PIN) {
171 mode = GET_DATA_MODE_ALL_IN_ONE_PIN_AUTH;
172 } else if (GetAuthType().value() == AuthType::PRIVATE_PIN) {
173 mode = GET_DATA_MODE_ALL_IN_ONE_PRIVATE_PIN_AUTH;
174 } else {
175 mode = GET_DATA_MODE_ALL_IN_ONE_RECOVERY_KEY_AUTH;
176 }
177 UserAuth::ExecutorParam executorParam = {
178 .tokenId = param.tokenId,
179 .authIntent = param.authIntent,
180 .scheduleId = scheduleId,
181 .userId = param.userId,
182 };
183 auto callback = sptr<IExecutorCallback>(new (std::nothrow) PinAuthExecutorCallbackHdi(callbackObj,
184 shared_from_this(), executorParam, mode));
185 if (callback == nullptr) {
186 IAM_LOGE("callback is null");
187 return UserAuth::ResultCode::GENERAL_ERROR;
188 }
189 if (param.templateIdList.size() == 0) {
190 IAM_LOGE("Error param");
191 return UserAuth::ResultCode::GENERAL_ERROR;
192 }
193 int32_t status = allInOneProxy_->Authenticate(scheduleId, param.templateIdList,
194 param.extraInfo, callback);
195 UserAuth::ResultCode result = ConvertHdiResultCode(status);
196 if (result != UserAuth::ResultCode::SUCCESS) {
197 IAM_LOGE("Authenticate fail ret=%{public}d", result);
198 return result;
199 }
200 return UserAuth::ResultCode::SUCCESS;
201 }
202
Delete(const std::vector<uint64_t> & templateIdList)203 UserAuth::ResultCode PinAuthAllInOneHdi::Delete(const std::vector<uint64_t> &templateIdList)
204 {
205 if (allInOneProxy_ == nullptr) {
206 IAM_LOGE("allInOneProxy is null");
207 return UserAuth::ResultCode::GENERAL_ERROR;
208 }
209 if (templateIdList.empty()) {
210 IAM_LOGE("templateIdList is empty");
211 return UserAuth::ResultCode::GENERAL_ERROR;
212 }
213 int32_t status = allInOneProxy_->Delete(templateIdList[0]);
214 UserAuth::ResultCode result = ConvertHdiResultCode(status);
215 if (result != UserAuth::ResultCode::SUCCESS) {
216 IAM_LOGE("Delete fail ret=%{public}d", result);
217 return result;
218 }
219 return UserAuth::ResultCode::SUCCESS;
220 }
221
Cancel(uint64_t scheduleId)222 UserAuth::ResultCode PinAuthAllInOneHdi::Cancel(uint64_t scheduleId)
223 {
224 if (allInOneProxy_ == nullptr) {
225 IAM_LOGE("allInOneProxy is null");
226 return UserAuth::ResultCode::GENERAL_ERROR;
227 }
228 int32_t status = allInOneProxy_->Cancel(scheduleId);
229 UserAuth::ResultCode result = ConvertHdiResultCode(status);
230 if (result != UserAuth::ResultCode::SUCCESS) {
231 IAM_LOGE("Cancel fail ret=%{public}d", result);
232 return result;
233 }
234 return UserAuth::ResultCode::SUCCESS;
235 }
236
GetProperty(const std::vector<uint64_t> & templateIdList,const std::vector<UserAuth::Attributes::AttributeKey> & keys,UserAuth::Property & property)237 UserAuth::ResultCode PinAuthAllInOneHdi::GetProperty(const std::vector<uint64_t> &templateIdList,
238 const std::vector<UserAuth::Attributes::AttributeKey> &keys, UserAuth::Property &property)
239 {
240 IF_FALSE_LOGE_AND_RETURN_VAL(allInOneProxy_ != nullptr, UserAuth::ResultCode::GENERAL_ERROR);
241
242 std::vector<int32_t> propertyTypes;
243 UserAuth::ResultCode result = ConvertAttributeKeyVectorToPropertyType(keys, propertyTypes);
244 IF_FALSE_LOGE_AND_RETURN_VAL(result == UserAuth::ResultCode::SUCCESS, UserAuth::ResultCode::GENERAL_ERROR);
245
246 Property hdiProperty;
247 int32_t status = allInOneProxy_->GetProperty(templateIdList, propertyTypes, hdiProperty);
248 result = ConvertHdiResultCode(status);
249 if (result != UserAuth::ResultCode::SUCCESS) {
250 IAM_LOGE("SendCommand fail result %{public}d", result);
251 return result;
252 }
253 MoveHdiProperty(hdiProperty, property);
254 return UserAuth::ResultCode::SUCCESS;
255 }
256
MoveHdiProperty(Property & in,UserAuth::Property & out)257 void PinAuthAllInOneHdi::MoveHdiProperty(Property &in, UserAuth::Property &out)
258 {
259 out.authSubType = in.authSubType;
260 out.lockoutDuration = in.lockoutDuration;
261 out.remainAttempts = in.remainAttempts;
262 out.nextFailLockoutDuration = in.nextFailLockoutDuration;
263 out.credentialLength = in.credentialLength;
264 }
265
ConvertAttributeKeyVectorToPropertyType(const std::vector<UserAuth::Attributes::AttributeKey> inItems,std::vector<int32_t> & outItems)266 UserAuth::ResultCode PinAuthAllInOneHdi::ConvertAttributeKeyVectorToPropertyType(
267 const std::vector<UserAuth::Attributes::AttributeKey> inItems, std::vector<int32_t> &outItems)
268 {
269 outItems.clear();
270 for (auto &inItem : inItems) {
271 if (inItem == UserAuth::Attributes::ATTR_ENROLL_PROGRESS ||
272 inItem == UserAuth::Attributes::ATTR_SENSOR_INFO) {
273 continue;
274 }
275 int32_t outItem;
276 UserAuth::ResultCode result = ConvertAttributeKeyToPropertyType(inItem, outItem);
277 IF_FALSE_LOGE_AND_RETURN_VAL(result == UserAuth::ResultCode::SUCCESS, UserAuth::ResultCode::GENERAL_ERROR);
278 outItems.push_back(outItem);
279 }
280
281 return UserAuth::ResultCode::SUCCESS;
282 }
283
ConvertAttributeKeyToPropertyType(const UserAuth::Attributes::AttributeKey in,int32_t & out)284 UserAuth::ResultCode PinAuthAllInOneHdi::ConvertAttributeKeyToPropertyType(const UserAuth::Attributes::AttributeKey in,
285 int32_t &out)
286 {
287 static const std::map<UserAuth::Attributes::AttributeKey, GetPropertyType> data = {
288 { UserAuth::Attributes::ATTR_PIN_SUB_TYPE, GetPropertyType::AUTH_SUB_TYPE },
289 { UserAuth::Attributes::ATTR_FREEZING_TIME, GetPropertyType::LOCKOUT_DURATION },
290 { UserAuth::Attributes::ATTR_REMAIN_TIMES, GetPropertyType::REMAIN_ATTEMPTS },
291 { UserAuth::Attributes::ATTR_NEXT_FAIL_LOCKOUT_DURATION, GetPropertyType::NEXT_FAIL_LOCKOUT_DURATION },
292 { UserAuth::Attributes::ATTR_CREDENTIAL_LENGTH, GetPropertyType::CREDENTIAL_LENGTH },
293 };
294
295 auto iter = data.find(in);
296 if (iter == data.end()) {
297 IAM_LOGE("attribute %{public}d is invalid", in);
298 return UserAuth::ResultCode::GENERAL_ERROR;
299 } else {
300 out = static_cast<int32_t>(iter->second);
301 }
302 IAM_LOGI("covert hdi result code %{public}d to framework result code %{public}d", in, out);
303 return UserAuth::ResultCode::SUCCESS;
304 }
305
SetAuthType(int32_t authType)306 void PinAuthAllInOneHdi::SetAuthType(int32_t authType)
307 {
308 std::lock_guard<std::mutex> lock(mutex_);
309 switch (authType) {
310 case AuthType::PIN:
311 IAM_LOGI("set authType is pin");
312 authType_ = authType;
313 break;
314 case AuthType::RECOVERY_KEY:
315 IAM_LOGI("set authType is recovery key");
316 authType_ = authType;
317 break;
318 case AuthType::PRIVATE_PIN:
319 IAM_LOGI("set authType is private pin");
320 authType_ = authType;
321 break;
322 default:
323 IAM_LOGE("authType value is error, set failed");
324 }
325 }
326
GetAuthType()327 std::optional<int32_t> PinAuthAllInOneHdi::GetAuthType()
328 {
329 std::lock_guard<std::mutex> lock(mutex_);
330 if (!authType_.has_value()) {
331 IAM_LOGE("authType_ not assigned a value");
332 return std::nullopt;
333 }
334
335 return authType_;
336 }
337
Abandon(uint64_t scheduleId,const UserAuth::DeleteParam & param,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)338 UserAuth::ResultCode PinAuthAllInOneHdi::Abandon(uint64_t scheduleId, const UserAuth::DeleteParam ¶m,
339 const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
340 {
341 if (allInOneProxy_ == nullptr) {
342 IAM_LOGE("allInOneProxy is null");
343 return UserAuth::ResultCode::GENERAL_ERROR;
344 }
345 if (callbackObj == nullptr) {
346 IAM_LOGE("callbackObj is null");
347 return UserAuth::ResultCode::GENERAL_ERROR;
348 }
349
350 UserAuth::ExecutorParam executorParam = {
351 .tokenId = param.tokenId,
352 .scheduleId = scheduleId,
353 .userId = param.userId,
354 };
355 auto callback = sptr<IExecutorCallback>(new (std::nothrow) PinAuthExecutorCallbackHdi(callbackObj,
356 shared_from_this(), executorParam, GET_DATA_MODE_NONE));
357 if (callback == nullptr) {
358 IAM_LOGE("callback is null");
359 return UserAuth::ResultCode::GENERAL_ERROR;
360 }
361 int32_t status = allInOneProxy_->Abandon(scheduleId, param.templateId, param.extraInfo, callback);
362 UserAuth::ResultCode result = ConvertHdiResultCode(status);
363 if (result != UserAuth::ResultCode::SUCCESS) {
364 IAM_LOGE("Abandon fail ret=%{public}d", result);
365 return result;
366 }
367 return UserAuth::ResultCode::SUCCESS;
368 }
369
SendCommand(UserAuth::PropertyMode commandId,const std::vector<uint8_t> & extraInfo,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)370 UserAuth::ResultCode PinAuthAllInOneHdi::SendCommand(UserAuth::PropertyMode commandId,
371 const std::vector<uint8_t> &extraInfo, const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
372 {
373 IF_FALSE_LOGE_AND_RETURN_VAL(allInOneProxy_ != nullptr, UserAuth::ResultCode::GENERAL_ERROR);
374 IF_FALSE_LOGE_AND_RETURN_VAL(callbackObj != nullptr, UserAuth::ResultCode::GENERAL_ERROR);
375 int32_t hdiCommandId;
376 UserAuth::ResultCode result = ConvertCommandId(commandId, hdiCommandId);
377 if (result != UserAuth::ResultCode::SUCCESS) {
378 IAM_LOGE("ConvertCommandId fail result %{public}d", result);
379 return result;
380 }
381 UserAuth::ExecutorParam executorParam = {};
382 sptr<IExecutorCallback> callback(new (std::nothrow) PinAuthExecutorCallbackHdi(callbackObj,
383 shared_from_this(), executorParam, GET_DATA_MODE_NONE));
384 IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, UserAuth::ResultCode::GENERAL_ERROR);
385 int32_t status = allInOneProxy_->SendCommand(hdiCommandId, extraInfo, callback);
386 result = ConvertResultCode(status);
387 if (result != UserAuth::ResultCode::SUCCESS) {
388 IAM_LOGE("SendCommand fail result %{public}d", result);
389 return result;
390 }
391 return UserAuth::ResultCode::SUCCESS;
392 }
393
ConvertCommandId(const UserAuth::PropertyMode in,int32_t & out)394 UserAuth::ResultCode PinAuthAllInOneHdi::ConvertCommandId(const UserAuth::PropertyMode in, int32_t &out)
395 {
396 if (static_cast<CommandId>(in) > CommandId::VENDOR_COMMAND_BEGIN) {
397 out = static_cast<CommandId>(in);
398 IAM_LOGI("vendor command id %{public}d, no covert", out);
399 return UserAuth::ResultCode::SUCCESS;
400 } else {
401 IAM_LOGE("command id %{public}d is invalid", in);
402 return UserAuth::ResultCode::INVALID_PARAMETERS;
403 }
404 }
405
ConvertResultCode(const int32_t in)406 UserAuth::ResultCode PinAuthAllInOneHdi::ConvertResultCode(const int32_t in)
407 {
408 HDF_STATUS hdfIn = static_cast<HDF_STATUS>(in);
409 static const std::map<HDF_STATUS, UserAuth::ResultCode> data = {
410 { HDF_SUCCESS, UserAuth::ResultCode::SUCCESS },
411 { HDF_FAILURE, UserAuth::ResultCode::GENERAL_ERROR },
412 { HDF_ERR_TIMEOUT, UserAuth::ResultCode::TIMEOUT },
413 { HDF_ERR_QUEUE_FULL, UserAuth::ResultCode::BUSY },
414 { HDF_ERR_DEVICE_BUSY, UserAuth::ResultCode::BUSY },
415 };
416
417 UserAuth::ResultCode out;
418 auto iter = data.find(hdfIn);
419 if (iter == data.end()) {
420 out = UserAuth::ResultCode::GENERAL_ERROR;
421 } else {
422 out = iter->second;
423 }
424 IAM_LOGI("covert hdi result code %{public}d to framework result code %{public}d", in, out);
425 return out;
426 }
427 } // namespace PinAuth
428 } // namespace UserIam
429 } // namespace OHOS
430