• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &param,
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 &param,
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 &param,
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