1# PIN Authentication 2 3## Overview 4 5### Function 6 7Personal Identification Number (PIN) authentication provides user authentication capabilities in identity authentication scenarios, such as device unlocking, payment, and app logins. After a user registers a PIN, the PIN authentication (Pin_auth) module unlocks the device only when the correct PIN is entered. The figure below shows the architecture of PIN authentication. 8 9The Pin_auth driver is developed based on the Hardware Driver Foundation (HDF). The Pin_auth driver model shields hardware differences and provides stable PIN authentication capabilities for the user User_auth framework (User_auth) and PIN authentication system ability (SA). The PIN authentication capabilities include obtaining the PIN authentication executor list, executor information, and anti-brute force information of the specified template, comparing the template ID list of the executor and that of User_auth, enrolling or deleting PINs, and performing PIN authentication. 10 11**Figure 1** PIN authentication architecture 12 13 14 15### Basic Concepts 16The identity authentication consists of User_auth and basic authentication services (including PIN authentication and facial recognition). It supports basic functions such as setting and deleting user credentials and performing authentication. 17 18- Executor 19 20 The executor collects, processes, stores, and compares data for authentication. Each authentication service provides the executor capabilities, which are scheduled by User_auth to implement basic capabilities. 21 22- Executor security level 23 24 Security level of the runtime environment when an executor provides capabilities. 25 26- Executor role 27 28 - Executor: independently completes the entire process of credential registration and identity authentication. The executor can collect, process, store, and compare data to complete the authentication. 29 30 - Collector: only collects data during user authentication. It needs to work with the authenticator to complete user authentication. 31 32 - Authenticator: only processes data, obtains the stored credential template, and compares it with the authentication information generated. 33 34- Executor type 35 36 The authentication algorithm varies depending on the authentication mode and device used. Different executor types are defined based on the supported algorithm type or the device in use. 37 38- User_auth public key & executor public key 39 40 To ensure user data security and authentication result accuracy, measures must be taken to protect the integrity of the key information exchanged between User_auth and basic authentication services. Public keys must be exchanged when the executor provided by a basic authentication service interworks with User_auth. 41 42 - The executor uses the User_auth public key to verify scheduling instructions. 43 44 - User_auth uses the executor public key to verify the authentication result accuracy and the integrity of the information exchanged with the executor. 45 46 47- PIN authentication credential template 48 49 Authentication credentials are generated and stored by the authentication service when users set authentication credentials. Each template has an ID to index a set of template information files. The template information needs to be compared with the authentication data generated during authentication to complete identity authentication. 50 51- Data verification by the executor 52 53 User_auth manages the mappings between user identities and credential IDs in a unified manner. When connecting to User_auth, the executor obtains the template ID list from User_auth and updates its template ID list based on the template ID list obtained. 54 55- IDL interface 56 57 An Interface Definition Language (IDL) is a language that lets a program or object written in one language communicate with another program written in an unknown language. An IDL compiler generates client stub files and server framework files. This document describes how to use the client and server generated by the IDL interface to implement communication between the Pin_auth service and driver. For details, see [IDL](https://gitee.com/openharmony/ability_idl_tool/blob/master/README.md). 58 59- IPC 60 61 Inter-Process Communication (IPC) is a mechanism that allows processes to communicate with each other. For details, see [IPC](https://gitee.com/openharmony/communication_ipc/blob/master/README.md). 62 63- HDI 64 65 The hardware device interface (HDI) is located between the basic system service layer and the device driver layer. It provides APIs for abstracting hardware device functions, which shields underlying hardware device differences for system services. For details, see [HDI Specifications](../../design/hdi-design-specifications.md). 66 67### Working Principles 68 69The Pin_auth driver provides basic PIN authentication capabilities for the upper-layer User_auth and Pin_auth service to ensure successful PIN authentication. You can develop drivers to call Hardware Device Interface (HDI) APIs based on the HDF and the chip you use. 70 71**Figure 2** Pin_auth service and Pin_auth driver APIs 72 73 74 75### Constraints 76PIN authentication must be implemented in a TEE, and the confidential information, such as PINs and credentials, must be stored in a TEE. 77## Development Guidelines 78 79### When to Use 80The Pin_auth driver provides basic PIN authentication capabilities for the User_auth and Pin_auth service to ensure successful PIN authentication. 81 82### Available APIs 83 84The following table describes the C++ APIs generated from the Interface Definition Language (IDL) interface description. For details about the interface declaration, see the .idl file in **/drivers/interface/pin_auth**. 85**Table 1** describes the HDI APIs for PIN credential enrollment, authentication, and deletion. **Table 2** describes the callbacks used to return the executor operation result to the framework or return the PIN entered by the user. 86 87**Table 1** Available APIs 88 89| API | Description | 90| ------------------------------- | ------------------------------------------- | 91| GetExecutorInfo(ExecutorInfo& executorInfo) | Obtains information about an executor.| 92| GetExecutorList(std::vector<sptr<V2_0::IAllInOneExecutor>>& allInOneExecutors, <br>std::vector<sptr<V2_0::IVerifier>>& verifiers, <br>std::vector<sptr<V2_0::ICollector>>& collectors) | Obtains the V2_0 executor list.| 93| OnRegisterFinish(const std::vector<uint64_t>& templateIdList,<br>const std::vector<uint8_t>& frameworkPublicKey,<br>const std::vector<uint8_t>& extraInfo) | Obtains the public key and template ID list from User_auth after the executor is registered successfully.| 94| Cancel(uint64_t scheduleId) | Cancels an operation. | 95| SetData(uint64_t scheduleId, uint64_t authSubType, <br>const std::vector<uint8_t> &data, int32_t resultCode) | Called to return the subtype of the PIN enrolled by the user and the anonymization PIN data. | 96| Enroll(uint64_t scheduleId, const std::vector<uint8_t>& extraInfo, <br>const sptr<IExecutorCallback>& callbackObj) | Enrolls a PIN. | 97| Authenticate(uint64_t scheduleId, const std::vector<uint64_t>& templateIdList, const std::vector<uint8_t>& extraInfo, const sptr<IExecutorCallback>& callbackObj) | Starts PIN authentication. | 98| Delete(uint64_t templateId) | Deletes a PIN template. | 99| GetProperty(const std::vector<uint64_t>& templateIdList, <br>const std::vector<GetPropertyType>& propertyTypes, Property& property) | Obtains executor property information.| 100 101 102**Table 2** Callbacks 103 104| API | Description | 105| ------------------------------------------------------------ | -------------------- | 106| IExecutorCallback::OnResult(int32_t result, const std::vector<uint8_t>& extraInfo) | Called to return the operation result.| 107| IExecutorCallback::OnTip(int32_t tip, const std::vector<uint8_t>& extraInfo) | Called to return the prompt information about the operation process.| 108| IExecutorCallback::OnGetData(const std::vector<uint8_t>& algoParameter, uint64_t authSubType, uint32_t algoVersion, const std::vector<uint8_t>& challenge)| Called to return the PIN information obtained. | 109| IExecutorCallback::OnMessage(int32_t destRole, const std::vector<uint8_t>& msg)| Called to return the interaction information about the operation process. | 110 111### How to Develop 112 113The following uses the RK3568 platform as an example to demonstrate how to develop the Pin_auth driver. <br/>The directory structure is as follows: 114 115```text 116// drivers/peripheral/pin_auth 117├── BUILD.gn # Build script 118├── bundle.json # Component description file 119├── test # Test cases 120└── hdi_service # Pin_auth driver implementation 121 ├── BUILD.gn # Build script 122 ├── adaptor # Implementation of related algorithms 123 ├── common # Implementation of common interfaces 124 ├── database # Database implementation 125 ├── main # Entry for implementing PIN-related functions 126 └── service # Entry for implementing the Pin_auth driver 127 ├── inc # Header files 128 └── src # Source files 129 ├── all_in_one_impl.cpp # Implementation of authentication and enrollment APIs for the all-in-one executor 130 ├── verifier_impl.cpp # Implementation of authentication and enrollment APIs for the verifier 131 ├── collector_impl.cpp # Implementation of authentication and enrollment APIs for the collector 132 ├── executor_impl_common.cpp # Utilities 133 ├── pin_auth_interface_driver.cpp # Pin_auth driver entry 134 └── pin_auth_interface_service.cpp # Implementation of the APIs for obtaining the executor list 135``` 136 137 138The development procedure is as follows: 139 1401. Develop the Pin_auth driver based on the HDF. The **Bind()**, **Init()**, **Release()**, and **Dispatch()** functions are used. For details about the code, see [pin_auth_interface_driver.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/pin_auth/hdi_service/service/src/pin_auth_interface_driver.cpp). 141 142 ```c++ 143 // Create the PinAuthInterfaceService object by using the custom HdfPinAuthInterfaceHost object, which consists of the IoService object and HDI service. 144 struct HdfPinAuthInterfaceHost { 145 struct IDeviceIoService ioService; 146 OHOS::sptr<OHOS::IRemoteObject> stub; 147 }; 148 149 // Enable the IPC service to call the response API. 150 static int32_t PinAuthInterfaceDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply) 151 { 152 IAM_LOGI("start"); 153 auto *hdfPinAuthInterfaceHost = CONTAINER_OF(client->device->service, 154 struct HdfPinAuthInterfaceHost, ioService); 155 156 OHOS::MessageParcel *dataParcel = nullptr; 157 OHOS::MessageParcel *replyParcel = nullptr; 158 OHOS::MessageOption option; 159 160 if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) { 161 IAM_LOGE("%{public}s:invalid data sbuf object to dispatch", __func__); 162 return HDF_ERR_INVALID_PARAM; 163 } 164 if (SbufToParcel(reply, &replyParcel) != HDF_SUCCESS) { 165 IAM_LOGE("%{public}s:invalid reply sbuf object to dispatch", __func__); 166 return HDF_ERR_INVALID_PARAM; 167 } 168 169 return hdfPinAuthInterfaceHost->stub->SendRequest(cmdId, *dataParcel, *replyParcel, option); 170 } 171 172 // Initialize the HdfPinAuthInterfaceDriver object. 173 static int HdfPinAuthInterfaceDriverInit(struct HdfDeviceObject *deviceObject) 174 { 175 IAM_LOGI("start"); 176 std::shared_ptr<OHOS::UserIAM::PinAuth::PinAuth> pinHdi = 177 OHOS::UserIAM::Common::MakeShared<OHOS::UserIAM::PinAuth::PinAuth>(); 178 constexpr uint32_t SUCCESS = 0; 179 if (pinHdi == nullptr || pinHdi->Init() != SUCCESS) { 180 IAM_LOGE("Pin hal init failed"); 181 return HDF_FAILURE; 182 } 183 return HDF_SUCCESS; 184 } 185 186 // Bind the service provided by the Pin_auth driver to the HDF. 187 static int HdfPinAuthInterfaceDriverBind(struct HdfDeviceObject *deviceObject) 188 { 189 IAM_LOGI("start"); 190 auto *hdfPinAuthInterfaceHost = new (std::nothrow) HdfPinAuthInterfaceHost; 191 if (hdfPinAuthInterfaceHost == nullptr) { 192 IAM_LOGE("%{public}s: failed to create HdfPinAuthInterfaceHost object", __func__); 193 return HDF_FAILURE; 194 } 195 196 hdfPinAuthInterfaceHost->ioService.Dispatch = PinAuthInterfaceDriverDispatch; 197 hdfPinAuthInterfaceHost->ioService.Open = NULL; 198 hdfPinAuthInterfaceHost->ioService.Release = NULL; 199 200 auto serviceImpl = IPinAuthInterface::Get(true); 201 if (serviceImpl == nullptr) { 202 IAM_LOGE("%{public}s: failed to get of implement service", __func__); 203 return HDF_FAILURE; 204 } 205 206 hdfPinAuthInterfaceHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl, 207 IPinAuthInterface::GetDescriptor()); 208 if (hdfPinAuthInterfaceHost->stub == nullptr) { 209 IAM_LOGE("%{public}s: failed to get stub object", __func__); 210 return HDF_FAILURE; 211 } 212 213 deviceObject->service = &hdfPinAuthInterfaceHost->ioService; 214 IAM_LOGI("success"); 215 return HDF_SUCCESS; 216 } 217 218 // Release resources of the Pin_auth driver. 219 static void HdfPinAuthInterfaceDriverRelease(struct HdfDeviceObject *deviceObject) 220 { 221 IAM_LOGI("start"); 222 auto *hdfPinAuthInterfaceHost = CONTAINER_OF(deviceObject->service, 223 struct HdfPinAuthInterfaceHost, ioService); 224 delete hdfPinAuthInterfaceHost; 225 IAM_LOGI("success"); 226 } 227 228 static struct HdfDriverEntry g_pinAuthInterfaceDriverEntry = { 229 .moduleVersion = 1, 230 .moduleName = "pinauth_interface_service", 231 .Bind = HdfPinAuthInterfaceDriverBind, 232 .Init = HdfPinAuthInterfaceDriverInit, 233 .Release = HdfPinAuthInterfaceDriverRelease, 234 }; 235 236 // Call HDF_INIT to register the driver entry with the HDF. When loading the driver, the HDF calls the Bind() function and then the Init() function. If the Init() function fails to be called, the HDF will call Release() to release driver resources and exit the driver model. 237 HDF_INIT(g_pinauthinterfaceDriverEntry); 238 ``` 239 240 241 2422. Obtain the executor list. For details about the code, see [pin_auth_interface_service.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/pin_auth/hdi_service/service/src/pin_auth_interface_service.cpp). 243 244 ```c++ 245 // Executor implementation class 246 class ExecutorImpl : public HdiIExecutor, public NoCopyable { 247 public: 248 explicit ExecutorImpl(std::shared_ptr<OHOS::UserIam::PinAuth::PinAuth> pinHdi); 249 ~ExecutorImpl() override; 250 251 int32_t GetExecutorInfo(HdiExecutorInfo &info) override; 252 int32_t OnRegisterFinish(const std::vector<uint64_t> &templateIdList, 253 const std::vector<uint8_t> &frameworkPublicKey, const std::vector<uint8_t> &extraInfo) override; 254 int32_t Cancel(uint64_t scheduleId) override; 255 int32_t SendMessage(uint64_t scheduleId, int32_t srcRole, const std::vector<uint8_t>& msg) override; 256 int32_t SetData(uint64_t scheduleId, uint64_t authSubType, const std::vector<uint8_t> &data, 257 int32_t resultCode) override; 258 int32_t Enroll(uint64_t scheduleId, const std::vector<uint8_t> &extraInfo, 259 const sptr<HdiIExecutorCallback> &callbackObj) override; 260 int32_t Authenticate(uint64_t scheduleId, const std::vector<uint64_t>& templateIdList, 261 const std::vector<uint8_t> &extraInfo, const sptr<HdiIExecutorCallback> &callbackObj) override; 262 int32_t Delete(uint64_t templateId) override; 263 int32_t GetProperty(const std::vector<uint64_t> &templateIdList, const std::vector<int32_t> &propertyTypes, 264 HdiProperty &property) override; 265 266 private: 267 class ScheduleMap { 268 public: 269 uint32_t AddScheduleInfo(const uint64_t scheduleId, const uint32_t commandId, 270 const sptr<HdiIExecutorCallback> callback, const uint64_t templateId, 271 const std::vector<uint8_t> algoParameter); 272 uint32_t GetScheduleInfo(const uint64_t scheduleId, uint32_t &commandId, sptr<HdiIExecutorCallback> &callback, 273 uint64_t &templateId, std::vector<uint8_t> &algoParameter); 274 uint32_t DeleteScheduleId(const uint64_t scheduleId); 275 276 private: 277 struct ScheduleInfo { 278 uint32_t commandId; 279 sptr<HdiIExecutorCallback> callback; 280 uint64_t templateId; 281 std::vector<uint8_t> algoParameter; 282 }; 283 284 std::mutex mutex_; 285 std::map<uint64_t, struct ScheduleInfo> scheduleInfo_; 286 }; 287 288 private: 289 void CallError(const sptr<HdiIExecutorCallback> &callbackObj, uint32_t errorCode); 290 int32_t AuthPin(uint64_t scheduleId, uint64_t templateId, 291 const std::vector<uint8_t> &data, std::vector<uint8_t> &resultTlv); 292 int32_t AuthenticateInner(uint64_t scheduleId, uint64_t templateId, std::vector<uint8_t> &algoParameter, 293 const sptr<HdiIExecutorCallback> &callbackObj); 294 int32_t EnrollInner(uint64_t scheduleId, const std::vector<uint8_t> &extraInfo, 295 const sptr<HdiIExecutorCallback> &callbackObj, std::vector<uint8_t> &algoParameter, uint32_t &algoVersion); 296 void ReportAuthenticate(uint64_t scheduleId, uint64_t templateId, PinAuthResultBigData pinAuthResultBigData); 297 std::shared_ptr<OHOS::UserIam::PinAuth::PinAuth> pinHdi_; 298 ScheduleMap scheduleMap_; 299 OHOS::ThreadPool threadPool_; 300 }; 301 302 // Obtain the executor list and create an executor (example only). 303 int32_t PinAuthInterfaceService::GetExecutorList(std::vector<sptr<HdiIExecutor>>& allInOneExecutors, 304 std::vector<sptr<HdiIVerifier>>& verifiers, std::vector<sptr<HdiICollector>>& collectors) 305 { 306 IAM_LOGI("start"); 307 static_cast<void>(verifiers); 308 static_cast<void>(collectors); 309 std::shared_ptr<OHOS::UserIam::PinAuth::PinAuth> pinHdi = 310 OHOS::UserIam::Common::MakeShared<OHOS::UserIam::PinAuth::PinAuth>(); 311 if (pinHdi == nullptr) { 312 IAM_LOGE("Generate pinHdi failed"); 313 return HDF_FAILURE; 314 } 315 sptr<HdiIExecutor> executor = new (std::nothrow) ExecutorImpl(pinHdi); 316 if (executor == nullptr) { 317 IAM_LOGE("Generate executor failed"); 318 return HDF_FAILURE; 319 } 320 allInOneExecutors.push_back(executor); 321 IAM_LOGI("end"); 322 return HDF_SUCCESS; 323 } 324 ``` 325 326 327 3283. Implement each function of the executor. For details about the code, see [all_in_one_impl.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/pin_auth/hdi_service/service/src/all_in_one_impl.cpp). 329 330 ```c++ 331 // Obtain executor information (example only). 332 int32_t ExecutorImpl::GetExecutorInfo(HdiExecutorInfo &info) 333 { 334 IAM_LOGI("start"); 335 if (pinHdi_ == nullptr) { 336 IAM_LOGE("pinHdi_ is nullptr"); 337 return HDF_FAILURE; 338 } 339 constexpr unsigned short SENSOR_ID = 1; 340 info.sensorId = SENSOR_ID; 341 info.executorMatcher = EXECUTOR_TYPE; 342 info.executorRole = HdiExecutorRole::ALL_IN_ONE; 343 info.authType = HdiAuthType::PIN; 344 uint32_t eslRet = 0; 345 int32_t result = pinHdi_->GetExecutorInfo(info.publicKey, eslRet); 346 if (result != SUCCESS) { 347 IAM_LOGE("Get ExecutorInfo failed, fail code : %{public}d", result); 348 return result; 349 } 350 info.esl = static_cast<HdiExecutorSecureLevel>(eslRet); 351 352 return HDF_SUCCESS; 353 } 354 355 // After the executor is successfully registered, obtain the public key and template ID list from User_auth and save the public key obtained. The executor compares its template ID list with the template ID list obtained and updates its template ID list. 356 int32_t ExecutorImpl::OnRegisterFinish(const std::vector<uint64_t> &templateIdList, 357 const std::vector<uint8_t> &frameworkPublicKey, const std::vector<uint8_t> &extraInfo) 358 { 359 IAM_LOGI("start"); 360 static_cast<void>(frameworkPublicKey); 361 static_cast<void>(extraInfo); 362 if (pinHdi_ == nullptr) { 363 IAM_LOGE("pinHdi_ is nullptr"); 364 return HDF_FAILURE; 365 } 366 int32_t result = pinHdi_->VerifyTemplateData(templateIdList); 367 if (result != SUCCESS) { 368 IAM_LOGE("Verify templateData failed"); 369 return result; 370 } 371 372 return HDF_SUCCESS; 373 } 374 375 // Enroll the PIN. 376 int32_t ExecutorImpl::Enroll(uint64_t scheduleId, const std::vector<uint8_t> &extraInfo, 377 const sptr<IExecutorCallback> &callbackObj) 378 { 379 IAM_LOGI("start"); 380 if (callbackObj == nullptr) { 381 IAM_LOGE("callbackObj is nullptr"); 382 return HDF_ERR_INVALID_PARAM; 383 } 384 if (pinHdi_ == nullptr) { 385 IAM_LOGE("pinHdi_ is nullptr"); 386 CallError(callbackObj, INVALID_PARAMETERS); 387 return HDF_SUCCESS; 388 } 389 std::vector<uint8_t> algoParameter; 390 uint32_t algoVersion = 0; 391 int32_t result = EnrollInner(scheduleId, extraInfo, callbackObj, algoParameter, algoVersion); 392 if (result != SUCCESS) { 393 IAM_LOGE("EnrollInner failed, fail code : %{public}d", result); 394 return HDF_SUCCESS; 395 } 396 397 std::vector<uint8_t> challenge; 398 result = callbackObj->OnGetData(algoParameter, 0, algoVersion, challenge); 399 if (result != SUCCESS) { 400 IAM_LOGE("Enroll Pin failed, fail code : %{public}d", result); 401 CallError(callbackObj, GENERAL_ERROR); 402 // If the enrollment fails, delete scheduleId of scheduleMap. 403 if (scheduleMap_.DeleteScheduleId(scheduleId) != HDF_SUCCESS) { 404 IAM_LOGI("delete scheduleId failed"); 405 } 406 } 407 408 return HDF_SUCCESS; 409 } 410 411 // Implement the callback for returning data. 412 int32_t ExecutorImpl::SetData(uint64_t scheduleId, uint64_t authSubType, const std::vector<uint8_t> &data, 413 int32_t resultCode) 414 { 415 IAM_LOGI("start"); 416 if (pinHdi_ == nullptr) { 417 IAM_LOGE("pinHdi_ is nullptr"); 418 return HDF_FAILURE; 419 } 420 std::vector<uint8_t> resultTlv; 421 int32_t result = GENERAL_ERROR; 422 constexpr uint32_t INVALID_ID = 2; 423 uint32_t commandId = INVALID_ID; 424 sptr<HdiIExecutorCallback> callback = nullptr; 425 uint64_t templateId = 0; 426 std::vector<uint8_t> algoParameter(0, 0); 427 if (scheduleMap_.GetScheduleInfo(scheduleId, commandId, callback, templateId, algoParameter) != HDF_SUCCESS) { 428 IAM_LOGE("Get ScheduleInfo failed, fail code : %{public}d", result); 429 return HDF_FAILURE; 430 } 431 if (resultCode != SUCCESS && callback != nullptr) { 432 IAM_LOGE("SetData failed, resultCode is %{public}d", resultCode); 433 CallError(callback, resultCode); 434 return resultCode; 435 } 436 switch (commandId) { 437 case ENROLL_PIN: 438 result = pinHdi_->EnrollPin(scheduleId, authSubType, algoParameter, data, resultTlv); 439 if (result != SUCCESS) { 440 IAM_LOGE("Enroll Pin failed, fail code : %{public}d", result); 441 } 442 break; 443 case AUTH_PIN: 444 result = AuthPin(scheduleId, templateId, data, resultTlv); 445 if (result != SUCCESS) { 446 IAM_LOGE("Auth Pin failed, fail code : %{public}d", result); 447 } 448 break; 449 default: 450 IAM_LOGE("Error commandId"); 451 } 452 453 if (callback == nullptr || callback->OnResult(result, resultTlv) != SUCCESS) { 454 IAM_LOGE("callbackObj Pin failed"); 455 } 456 // Delete scheduleId from scheduleMap when the enrollment and authentication are successful. 457 if (scheduleMap_.DeleteScheduleId(scheduleId) != HDF_SUCCESS) { 458 IAM_LOGI("delete scheduleId failed"); 459 } 460 461 return HDF_SUCCESS; 462 } 463 464 // Perform PIN authentication. 465 int32_t ExecutorImpl::Authenticate(uint64_t scheduleId, const std::vector<uint64_t>& templateIdList, 466 const std::vector<uint8_t> &extraInfo, const sptr<HdiIExecutorCallback> &callbackObj) 467 { 468 IAM_LOGI("start"); 469 if (callbackObj == nullptr) { 470 IAM_LOGE("callbackObj is nullptr"); 471 return HDF_ERR_INVALID_PARAM; 472 } 473 if (pinHdi_ == nullptr || templateIdList.size() != 1) { 474 IAM_LOGE("pinHdi_ is nullptr or templateIdList size not 1"); 475 CallError(callbackObj, INVALID_PARAMETERS); 476 return HDF_SUCCESS; 477 } 478 static_cast<void>(extraInfo); 479 std::vector<uint8_t> algoParameter; 480 uint32_t algoVersion = 0; 481 uint64_t templateId = templateIdList[0]; 482 int32_t result = pinHdi_->GetAlgoParameter(templateId, algoParameter, algoVersion); 483 if (result != SUCCESS) { 484 IAM_LOGE("Get algorithm parameter failed, fail code : %{public}d", result); 485 CallError(callbackObj, result); 486 return GENERAL_ERROR; 487 } 488 result = AuthenticateInner(scheduleId, templateId, algoParameter, callbackObj); 489 if (result != SUCCESS) { 490 IAM_LOGE("AuthenticateInner failed, fail code : %{public}d", result); 491 return HDF_SUCCESS; 492 } 493 494 std::vector<uint8_t> challenge; 495 result = callbackObj->OnGetData(algoParameter, 0, algoVersion, challenge); 496 if (result != SUCCESS) { 497 IAM_LOGE("Authenticate Pin failed, fail code : %{public}d", result); 498 CallError(callbackObj, GENERAL_ERROR); 499 // If the authentication fails, delete scheduleId of scheduleMap. 500 if (scheduleMap_.DeleteScheduleId(scheduleId) != HDF_SUCCESS) { 501 IAM_LOGI("delete scheduleId failed"); 502 } 503 } 504 505 return HDF_SUCCESS; 506 } 507 508 // Delete the PIN template. 509 int32_t ExecutorImpl::Delete(uint64_t templateId) 510 { 511 IAM_LOGI("start"); 512 if (pinHdi_ == nullptr) { 513 IAM_LOGE("pinHdi_ is nullptr"); 514 return HDF_FAILURE; 515 } 516 int32_t result = pinHdi_->DeleteTemplate(templateId); 517 if (result != SUCCESS) { 518 IAM_LOGE("Verify templateData failed, fail code : %{public}d", result); 519 return result; 520 } 521 522 return HDF_SUCCESS; 523 } 524 525 // Cancel the operation based on the specified scheduleId. 526 int32_t ExecutorImpl::Cancel(uint64_t scheduleId) 527 { 528 IAM_LOGI("start"); 529 if (scheduleMap_.DeleteScheduleId(scheduleId) != HDF_SUCCESS) { 530 IAM_LOGE("scheduleId is not found"); 531 return HDF_FAILURE; 532 } 533 return HDF_SUCCESS; 534 } 535 536 // Obtain the executor property information. 537 int32_t ExecutorImpl::GetProperty( 538 const std::vector<uint64_t> &templateIdList, const std::vector<GetPropertyType> &propertyTypes, Property &property) 539 { 540 IAM_LOGI("start"); 541 if (pinHdi_ == nullptr) { 542 IAM_LOGE("pinHdi_ is nullptr"); 543 return HDF_FAILURE; 544 } 545 546 if (templateIdList.size() != 1) { 547 IAM_LOGE("templateIdList size is not 1"); 548 return HDF_FAILURE; 549 } 550 551 uint64_t templateId = templateIdList[0]; 552 OHOS::UserIam::PinAuth::PinCredentialInfo infoRet = {}; 553 int32_t result = pinHdi_->QueryPinInfo(templateId, infoRet); 554 if (result != SUCCESS) { 555 IAM_LOGE("Get TemplateInfo failed, fail code : %{public}d", result); 556 return HDF_FAILURE; 557 } 558 559 property.authSubType = infoRet.subType; 560 property.remainAttempts = infoRet.remainTimes; 561 property.lockoutDuration = infoRet.freezingTime; 562 return HDF_SUCCESS; 563 } 564 ``` 565 566 567### Verification 568Verify whether PIN authentication can be successfully performed on the RK3568 platform as follows: 569 5701. Touch **Settings** > **Biometrics & passwords** > **Password**, and enter your password. 5712. Press the power button to lock the screen. Press the power button again and enter the password. The screen is unlocked if a correct password is entered. 5723. Touch **Settings** > **Biometrics & passwords** > **Password**, and verify **Disable lock screen password** and **Change lock screen password**. 5734. After step 1 is complete, enter incorrect passwords for a specified number of times to check whether the anti-brute force cracking capability is normal. For example, if you enter incorrect passwords for five consecutive times, the device will be frozen for 60s. 574