• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "executor_impl.h"
17 #include <hdf_base.h>
18 #include <securec.h>
19 #include "defines.h"
20 #include "iam_logger.h"
21 
22 #define LOG_LABEL OHOS::UserIam::Common::LABEL_PIN_AUTH_IMPL
23 
24 namespace OHOS {
25 namespace HDI {
26 namespace PinAuth {
27 namespace {
28     constexpr uint32_t EXECUTOR_TYPE = 0;
29     constexpr uint32_t ENROLL_PIN = 0;
30     constexpr uint32_t AUTH_PIN = 1;
31     constexpr uint32_t GENERAL_ERROR = 2;
32     constexpr uint32_t SUCCESS = 0;
33 } // namespace
34 
ExecutorImpl(std::shared_ptr<OHOS::UserIam::PinAuth::PinAuth> pinHdi)35 ExecutorImpl::ExecutorImpl(std::shared_ptr<OHOS::UserIam::PinAuth::PinAuth> pinHdi)
36     : pinHdi_(pinHdi),
37       threadPool_("pin_async")
38 {
39     threadPool_.Start(1);
40 }
41 
~ExecutorImpl()42 ExecutorImpl::~ExecutorImpl()
43 {
44     threadPool_.Stop();
45 }
46 
GetExecutorInfo(ExecutorInfo & info)47 int32_t ExecutorImpl::GetExecutorInfo(ExecutorInfo &info)
48 {
49     IAM_LOGI("start");
50     if (pinHdi_ == nullptr) {
51         IAM_LOGE("pinHdi_ is nullptr");
52         return HDF_FAILURE;
53     }
54     constexpr unsigned short SENSOR_ID = 1;
55     info.sensorId = SENSOR_ID;
56     info.executorType = EXECUTOR_TYPE;
57     info.executorRole = ExecutorRole::ALL_IN_ONE;
58     info.authType = AuthType::PIN;
59     uint32_t eslRet = 0;
60     int32_t result = pinHdi_->GetExecutorInfo(info.publicKey, eslRet);
61     if (result != SUCCESS) {
62         IAM_LOGE("Get ExecutorInfo failed, fail code : %{public}d", result);
63         return result;
64     }
65     info.esl = static_cast<ExecutorSecureLevel>(eslRet);
66 
67     return HDF_SUCCESS;
68 }
69 
GetTemplateInfo(uint64_t templateId,TemplateInfo & info)70 int32_t ExecutorImpl::GetTemplateInfo(uint64_t templateId, TemplateInfo &info)
71 {
72     IAM_LOGI("start");
73     if (pinHdi_ == nullptr) {
74         IAM_LOGE("pinHdi_ is nullptr");
75         return HDF_FAILURE;
76     }
77     OHOS::UserIam::PinAuth::PinCredentialInfo infoRet = {};
78     int32_t result = pinHdi_->QueryPinInfo(templateId, infoRet);
79     if (result != SUCCESS) {
80         IAM_LOGE("Get TemplateInfo failed, fail code : %{public}d", result);
81         return result;
82     }
83     /* subType is stored in extraInfo */
84     info.extraInfo.resize(sizeof(infoRet.subType));
85     if (memcpy_s(&(info.extraInfo[0]), sizeof(infoRet.subType), &(infoRet.subType), sizeof(infoRet.subType)) != EOK) {
86         IAM_LOGE("copy subType to extraInfo fail!");
87         return HDF_FAILURE;
88     }
89 
90     info.executorType = EXECUTOR_TYPE;
91     info.remainAttempts = infoRet.remainTimes;
92     info.lockoutDuration = infoRet.freezingTime;
93 
94     return HDF_SUCCESS;
95 }
96 
OnRegisterFinish(const std::vector<uint64_t> & templateIdList,const std::vector<uint8_t> & frameworkPublicKey,const std::vector<uint8_t> & extraInfo)97 int32_t ExecutorImpl::OnRegisterFinish(const std::vector<uint64_t> &templateIdList,
98     const std::vector<uint8_t> &frameworkPublicKey, const std::vector<uint8_t> &extraInfo)
99 {
100     IAM_LOGI("start");
101     static_cast<void>(frameworkPublicKey);
102     static_cast<void>(extraInfo);
103     if (pinHdi_ == nullptr) {
104         IAM_LOGE("pinHdi_ is nullptr");
105         return HDF_FAILURE;
106     }
107     int32_t result = pinHdi_->VerifyTemplateData(templateIdList);
108     if (result != SUCCESS) {
109         IAM_LOGE("Verify templateData failed");
110         return result;
111     }
112 
113     return HDF_SUCCESS;
114 }
115 
CallError(const sptr<IExecutorCallbackV1_0> & callbackObj,uint32_t errorCode)116 void ExecutorImpl::CallError(const sptr<IExecutorCallbackV1_0> &callbackObj, uint32_t errorCode)
117 {
118     IAM_LOGI("start");
119     std::vector<uint8_t> ret(0);
120     if (callbackObj->OnResult(errorCode, ret) != SUCCESS) {
121         IAM_LOGE("callback failed");
122     }
123 }
124 
EnrollInner(uint64_t scheduleId,const std::vector<uint8_t> & extraInfo,const sptr<IExecutorCallbackV1_0> & callbackObj,std::vector<uint8_t> & algoParameter,uint32_t & algoVersion)125 int32_t ExecutorImpl::EnrollInner(uint64_t scheduleId, const std::vector<uint8_t> &extraInfo,
126     const sptr<IExecutorCallbackV1_0> &callbackObj, std::vector<uint8_t> &algoParameter, uint32_t &algoVersion)
127 {
128     IAM_LOGI("start");
129     static_cast<void>(extraInfo);
130     if (pinHdi_->GenerateAlgoParameter(algoParameter, algoVersion) != SUCCESS) {
131         IAM_LOGE("Generate algorithm parameter failed");
132         CallError(callbackObj, GENERAL_ERROR);
133         return GENERAL_ERROR;
134     }
135 
136     int32_t result = scheduleMap_.AddScheduleInfo(scheduleId, ENROLL_PIN, callbackObj, 0, algoParameter);
137     if (result != HDF_SUCCESS) {
138         IAM_LOGE("Add scheduleInfo failed, fail code : %{public}d", result);
139         CallError(callbackObj, GENERAL_ERROR);
140         return GENERAL_ERROR;
141     }
142 
143     return HDF_SUCCESS;
144 }
145 
Enroll(uint64_t scheduleId,const std::vector<uint8_t> & extraInfo,const sptr<IExecutorCallbackV1_0> & callbackObj)146 int32_t ExecutorImpl::Enroll(uint64_t scheduleId, const std::vector<uint8_t> &extraInfo,
147     const sptr<IExecutorCallbackV1_0> &callbackObj)
148 {
149     IAM_LOGI("start");
150     if (callbackObj == nullptr) {
151         IAM_LOGE("callbackObj is nullptr");
152         return HDF_ERR_INVALID_PARAM;
153     }
154     if (pinHdi_ == nullptr) {
155         IAM_LOGE("pinHdi_ is nullptr");
156         CallError(callbackObj, INVALID_PARAMETERS);
157         return HDF_SUCCESS;
158     }
159     std::vector<uint8_t> algoParameter;
160     uint32_t algoVersion = 0;
161     int32_t result = EnrollInner(scheduleId, extraInfo, callbackObj, algoParameter, algoVersion);
162     if (result != SUCCESS) {
163         IAM_LOGE("EnrollInner failed, fail code : %{public}d", result);
164         return HDF_SUCCESS;
165     }
166     result = callbackObj->OnGetData(scheduleId, algoParameter, 0);
167     if (result != SUCCESS) {
168         IAM_LOGE("Enroll Pin failed, fail code : %{public}d", result);
169         CallError(callbackObj, GENERAL_ERROR);
170         // If the enroll fails, delete scheduleId of scheduleMap
171         if (scheduleMap_.DeleteScheduleId(scheduleId) != HDF_SUCCESS) {
172             IAM_LOGI("delete scheduleId failed");
173         }
174     }
175 
176     return HDF_SUCCESS;
177 }
178 
EnrollV1_1(uint64_t scheduleId,const std::vector<uint8_t> & extraInfo,const sptr<IExecutorCallback> & callbackObj)179 int32_t ExecutorImpl::EnrollV1_1(uint64_t scheduleId, const std::vector<uint8_t> &extraInfo,
180     const sptr<IExecutorCallback> &callbackObj)
181 {
182     IAM_LOGI("start");
183     if (callbackObj == nullptr) {
184         IAM_LOGE("callbackObj is nullptr");
185         return HDF_ERR_INVALID_PARAM;
186     }
187     if (pinHdi_ == nullptr) {
188         IAM_LOGE("pinHdi_ is nullptr");
189         CallError(callbackObj, INVALID_PARAMETERS);
190         return HDF_SUCCESS;
191     }
192     std::vector<uint8_t> algoParameter;
193     uint32_t algoVersion = 0;
194     int32_t result = EnrollInner(scheduleId, extraInfo, callbackObj, algoParameter, algoVersion);
195     if (result != SUCCESS) {
196         IAM_LOGE("EnrollInner failed, fail code : %{public}d", result);
197         return HDF_SUCCESS;
198     }
199     result = callbackObj->OnGetDataV1_1(scheduleId, algoParameter, 0, algoVersion);
200     if (result != SUCCESS) {
201         IAM_LOGE("Enroll Pin failed, fail code : %{public}d", result);
202         CallError(callbackObj, GENERAL_ERROR);
203         // If the enroll fails, delete scheduleId of scheduleMap
204         if (scheduleMap_.DeleteScheduleId(scheduleId) != HDF_SUCCESS) {
205             IAM_LOGI("delete scheduleId failed");
206         }
207     }
208 
209     return HDF_SUCCESS;
210 }
211 
Authenticate(uint64_t scheduleId,uint64_t templateId,const std::vector<uint8_t> & extraInfo,const sptr<IExecutorCallbackV1_0> & callbackObj)212 int32_t ExecutorImpl::Authenticate(uint64_t scheduleId, uint64_t templateId, const std::vector<uint8_t> &extraInfo,
213     const sptr<IExecutorCallbackV1_0> &callbackObj)
214 {
215     IAM_LOGI("start");
216     if (callbackObj == nullptr) {
217         IAM_LOGE("callbackObj is nullptr");
218         return HDF_ERR_INVALID_PARAM;
219     }
220     if (pinHdi_ == nullptr) {
221         IAM_LOGE("pinHdi_ is nullptr");
222         CallError(callbackObj, INVALID_PARAMETERS);
223         return HDF_SUCCESS;
224     }
225     std::vector<uint8_t> algoParameter;
226     int32_t result = AuthenticateInner(scheduleId, templateId, algoParameter, callbackObj);
227     if (result != SUCCESS) {
228         IAM_LOGE("AuthenticateInner failed, fail code : %{public}d", result);
229         return HDF_SUCCESS;
230     }
231     result = callbackObj->OnGetData(scheduleId, algoParameter, 0);
232     if (result != SUCCESS) {
233         IAM_LOGE("Authenticate Pin failed, fail code : %{public}d", result);
234         CallError(callbackObj, GENERAL_ERROR);
235         // If the authentication fails, delete scheduleId of scheduleMap
236         if (scheduleMap_.DeleteScheduleId(scheduleId) != HDF_SUCCESS) {
237             IAM_LOGI("delete scheduleId failed");
238         }
239     }
240 
241     return HDF_SUCCESS;
242 }
243 
AuthenticateInner(uint64_t scheduleId,uint64_t templateId,std::vector<uint8_t> & algoParameter,const sptr<IExecutorCallbackV1_0> & callbackObj)244 int32_t ExecutorImpl::AuthenticateInner(uint64_t scheduleId, uint64_t templateId, std::vector<uint8_t> &algoParameter,
245     const sptr<IExecutorCallbackV1_0> &callbackObj)
246 {
247     IAM_LOGI("start");
248     OHOS::UserIam::PinAuth::PinCredentialInfo infoRet = {};
249     int32_t result = pinHdi_->QueryPinInfo(templateId, infoRet);
250     if (result != SUCCESS) {
251         IAM_LOGE("Get TemplateInfo failed, fail code : %{public}d", result);
252         CallError(callbackObj, result);
253         return GENERAL_ERROR;
254     }
255     if (infoRet.remainTimes == 0 || infoRet.freezingTime > 0) {
256         IAM_LOGE("Pin authentication is now frozen state");
257         CallError(callbackObj, LOCKED);
258         return GENERAL_ERROR;
259     }
260     result = scheduleMap_.AddScheduleInfo(scheduleId, AUTH_PIN, callbackObj, templateId, algoParameter);
261     if (result != HDF_SUCCESS) {
262         IAM_LOGE("Add scheduleInfo failed, fail code : %{public}d", result);
263         CallError(callbackObj, GENERAL_ERROR);
264         return GENERAL_ERROR;
265     }
266 
267     return SUCCESS;
268 }
269 
AuthenticateV1_1(uint64_t scheduleId,uint64_t templateId,const std::vector<uint8_t> & extraInfo,const sptr<IExecutorCallback> & callbackObj)270 int32_t ExecutorImpl::AuthenticateV1_1(uint64_t scheduleId, uint64_t templateId, const std::vector<uint8_t> &extraInfo,
271     const sptr<IExecutorCallback> &callbackObj)
272 {
273     IAM_LOGI("start");
274     if (callbackObj == nullptr) {
275         IAM_LOGE("callbackObj is nullptr");
276         return HDF_ERR_INVALID_PARAM;
277     }
278     if (pinHdi_ == nullptr) {
279         IAM_LOGE("pinHdi_ is nullptr");
280         CallError(callbackObj, INVALID_PARAMETERS);
281         return HDF_SUCCESS;
282     }
283     static_cast<void>(extraInfo);
284     std::vector<uint8_t> algoParameter;
285     uint32_t algoVersion = 0;
286     int32_t result = pinHdi_->GetAlgoParameter(templateId, algoParameter, algoVersion);
287     if (result != SUCCESS) {
288         IAM_LOGE("Get algorithm parameter failed, fail code : %{public}d", result);
289         CallError(callbackObj, result);
290         return GENERAL_ERROR;
291     }
292     result = AuthenticateInner(scheduleId, templateId, algoParameter, callbackObj);
293     if (result != SUCCESS) {
294         IAM_LOGE("AuthenticateInner failed, fail code : %{public}d", result);
295         return HDF_SUCCESS;
296     }
297 
298     result = callbackObj->OnGetDataV1_1(scheduleId, algoParameter, 0, algoVersion);
299     if (result != SUCCESS) {
300         IAM_LOGE("Authenticate Pin failed, fail code : %{public}d", result);
301         CallError(callbackObj, GENERAL_ERROR);
302         // If the authentication fails, delete scheduleId of scheduleMap
303         if (scheduleMap_.DeleteScheduleId(scheduleId) != HDF_SUCCESS) {
304             IAM_LOGI("delete scheduleId failed");
305         }
306     }
307 
308     return HDF_SUCCESS;
309 }
310 
AuthPin(uint64_t scheduleId,uint64_t templateId,const std::vector<uint8_t> & data,std::vector<uint8_t> & resultTlv)311 int32_t ExecutorImpl::AuthPin(uint64_t scheduleId, uint64_t templateId,
312     const std::vector<uint8_t> &data, std::vector<uint8_t> &resultTlv)
313 {
314     int32_t result = pinHdi_->AuthPin(scheduleId, templateId, data, resultTlv);
315     if (result != SUCCESS) {
316         IAM_LOGE("Auth Pin failed, fail code : %{public}d", result);
317         return result;
318     }
319     threadPool_.AddTask([hdi = pinHdi_, id = templateId]() {
320         if (hdi == nullptr) {
321             return;
322         }
323         hdi->WriteAntiBrute(id);
324     });
325     IAM_LOGI("Auth Pin success");
326     return result;
327 }
328 
OnSetData(uint64_t scheduleId,uint64_t authSubType,const std::vector<uint8_t> & data)329 int32_t ExecutorImpl::OnSetData(uint64_t scheduleId, uint64_t authSubType, const std::vector<uint8_t> &data)
330 {
331     IAM_LOGI("start");
332     if (pinHdi_ == nullptr) {
333         IAM_LOGE("pinHdi_ is nullptr");
334         return HDF_FAILURE;
335     }
336     std::vector<uint8_t> resultTlv;
337     int32_t result = GENERAL_ERROR;
338     constexpr uint32_t INVALID_ID = 2;
339     uint32_t commandId = INVALID_ID;
340     sptr<IExecutorCallbackV1_0> callback = nullptr;
341     uint64_t templateId = 0;
342     std::vector<uint8_t> algoParameter(0, 0);
343     if (scheduleMap_.GetScheduleInfo(scheduleId, commandId, callback, templateId, algoParameter) != HDF_SUCCESS) {
344         IAM_LOGE("Get ScheduleInfo failed, fail code : %{public}d", result);
345         return HDF_FAILURE;
346     }
347     switch (commandId) {
348         case ENROLL_PIN:
349             result = pinHdi_->EnrollPin(scheduleId, authSubType, algoParameter, data, resultTlv);
350             if (result != SUCCESS) {
351                 IAM_LOGE("Enroll Pin failed, fail code : %{public}d", result);
352             }
353             break;
354         case AUTH_PIN:
355             result = AuthPin(scheduleId, templateId, data, resultTlv);
356             if (result != SUCCESS) {
357                 IAM_LOGE("Auth Pin failed, fail code : %{public}d", result);
358             }
359             break;
360         default:
361             IAM_LOGE("Error commandId");
362     }
363 
364     if (callback == nullptr || callback->OnResult(result, resultTlv) != SUCCESS) {
365         IAM_LOGE("callbackObj Pin failed");
366     }
367     // Delete scheduleId from the scheduleMap_ when the enroll and authentication are successful
368     if (scheduleMap_.DeleteScheduleId(scheduleId) != HDF_SUCCESS) {
369         IAM_LOGI("delete scheduleId failed");
370     }
371 
372     return HDF_SUCCESS;
373 }
374 
Delete(uint64_t templateId)375 int32_t ExecutorImpl::Delete(uint64_t templateId)
376 {
377     IAM_LOGI("start");
378     if (pinHdi_ == nullptr) {
379         IAM_LOGE("pinHdi_ is nullptr");
380         return HDF_FAILURE;
381     }
382     int32_t result = pinHdi_->DeleteTemplate(templateId);
383     if (result != SUCCESS) {
384         IAM_LOGE("Verify templateData failed, fail code : %{public}d", result);
385         return result;
386     }
387 
388     return HDF_SUCCESS;
389 }
390 
Cancel(uint64_t scheduleId)391 int32_t ExecutorImpl::Cancel(uint64_t scheduleId)
392 {
393     IAM_LOGI("start");
394     if (scheduleMap_.DeleteScheduleId(scheduleId) != HDF_SUCCESS) {
395         IAM_LOGE("scheduleId is not found");
396         return HDF_FAILURE;
397     }
398     return HDF_SUCCESS;
399 }
400 
SendCommand(int32_t commandId,const std::vector<uint8_t> & extraInfo,const sptr<IExecutorCallbackV1_0> & callbackObj)401 int32_t ExecutorImpl::SendCommand(int32_t commandId, const std::vector<uint8_t> &extraInfo,
402     const sptr<IExecutorCallbackV1_0> &callbackObj)
403 {
404     IAM_LOGI("Extension interface, temporarily useless");
405     static_cast<void>(commandId);
406     static_cast<void>(extraInfo);
407     static_cast<void>(callbackObj);
408     return HDF_SUCCESS;
409 }
410 
AddScheduleInfo(const uint64_t scheduleId,const uint32_t commandId,const sptr<IExecutorCallbackV1_0> callback,const uint64_t templateId,const std::vector<uint8_t> algoParameter)411 uint32_t ExecutorImpl::ScheduleMap::AddScheduleInfo(const uint64_t scheduleId, const uint32_t commandId,
412     const sptr<IExecutorCallbackV1_0> callback, const uint64_t templateId, const std::vector<uint8_t> algoParameter)
413 {
414     IAM_LOGI("start");
415     std::lock_guard<std::mutex> guard(mutex_);
416     if (callback == nullptr) {
417         IAM_LOGE("callback is nullptr");
418         return HDF_ERR_INVALID_PARAM;
419     }
420     struct ExecutorImpl::ScheduleMap::ScheduleInfo info {
421         .commandId = commandId,
422         .callback = callback,
423         .templateId = templateId,
424         .algoParameter = algoParameter
425     };
426     scheduleInfo_[scheduleId] = info;
427 
428     return HDF_SUCCESS;
429 }
430 
GetScheduleInfo(const uint64_t scheduleId,uint32_t & commandId,sptr<IExecutorCallbackV1_0> & callback,uint64_t & templateId,std::vector<uint8_t> & algoParameter)431 uint32_t ExecutorImpl::ScheduleMap::GetScheduleInfo(const uint64_t scheduleId, uint32_t &commandId,
432     sptr<IExecutorCallbackV1_0> &callback, uint64_t &templateId, std::vector<uint8_t> &algoParameter)
433 {
434     IAM_LOGI("start");
435     std::lock_guard<std::mutex> guard(mutex_);
436     if (scheduleInfo_.find(scheduleId) == scheduleInfo_.end()) {
437         IAM_LOGE("scheduleId is invalid");
438         return HDF_FAILURE;
439     }
440     commandId = scheduleInfo_[scheduleId].commandId;
441     callback = scheduleInfo_[scheduleId].callback;
442     templateId = scheduleInfo_[scheduleId].templateId;
443     algoParameter = scheduleInfo_[scheduleId].algoParameter;
444 
445     return HDF_SUCCESS;
446 }
447 
DeleteScheduleId(const uint64_t scheduleId)448 uint32_t ExecutorImpl::ScheduleMap::DeleteScheduleId(const uint64_t scheduleId)
449 {
450     IAM_LOGI("start");
451     std::lock_guard<std::mutex> guard(mutex_);
452     if (scheduleInfo_.erase(scheduleId) == 1) {
453         IAM_LOGI("Delete scheduleId succ");
454         return HDF_SUCCESS;
455     }
456     IAM_LOGE("Delete scheduleId fail");
457     return HDF_FAILURE;
458 }
459 
GetProperty(const std::vector<uint64_t> & templateIdList,const std::vector<GetPropertyType> & propertyTypes,Property & property)460 int32_t ExecutorImpl::GetProperty(
461     const std::vector<uint64_t> &templateIdList, const std::vector<GetPropertyType> &propertyTypes, Property &property)
462 {
463     IAM_LOGI("start");
464     if (pinHdi_ == nullptr) {
465         IAM_LOGE("pinHdi_ is nullptr");
466         return HDF_FAILURE;
467     }
468 
469     if (templateIdList.size() != 1) {
470         IAM_LOGE("templateIdList size is not 1");
471         return HDF_ERR_INVALID_PARAM;
472     }
473 
474     uint64_t templateId = templateIdList[0];
475     OHOS::UserIam::PinAuth::PinCredentialInfo infoRet = {};
476     int32_t result = pinHdi_->QueryPinInfo(templateId, infoRet);
477     if (result != SUCCESS) {
478         IAM_LOGE("Get TemplateInfo failed, fail code : %{public}d", result);
479         return HDF_FAILURE;
480     }
481 
482     property.authSubType = infoRet.subType;
483     property.remainAttempts = infoRet.remainTimes;
484     property.lockoutDuration = infoRet.freezingTime;
485     return HDF_SUCCESS;
486 }
487 } // PinAuth
488 } // HDI
489 } // OHOS