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