1e41f4b71Sopenharmony_ci# Fingerprint Authentication
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## Overview
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ci### Function
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciFingerprint authentication is indispensable in identity authentication scenarios, such as device unlocking, payment, and app logins. The fingerprint authentication (Fingerprint_auth) module provides fingerprint authentication for a device after a user enrolls a fingerprint. The figure below shows the fingerprint authentication architecture.
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ciThe Fingerprint_auth driver is developed based on the Hardware Driver Foundation (HDF). It shields hardware differences and provides stable fingerprint authentication capabilities for the upper-layer user authentication (User_auth) framework and Fingerprint_auth service. It provides APIs for obtaining the fingerprint authentication executor list, executor information, and template information by template ID, comparing fingerprint template information of the executor and that of User_auth, enrolling or deleting fingerprints, and performing fingerprint authentication.
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci**Figure 1** Fingerprint authentication architecture
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci![image](figures/fingerprint_auth_architecture.png "Fingerprint authentication architecture")
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ci### Basic Concepts
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ciThe identity authentication consists of the User_auth framework and basic authentication services. It supports basic functions such as setting and deleting user credentials and performing authentication. The system supports user identity authentication and data collection, processing, storage, and comparison.
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- Authentication credential
47e41f4b71Sopenharmony_ci
48e41f4b71Sopenharmony_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.
49e41f4b71Sopenharmony_ci
50e41f4b71Sopenharmony_ci- Data verification by the executor
51e41f4b71Sopenharmony_ci
52e41f4b71Sopenharmony_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.
53e41f4b71Sopenharmony_ci
54e41f4b71Sopenharmony_ci- HAPs
55e41f4b71Sopenharmony_ci
56e41f4b71Sopenharmony_ci  In a broad sense, Harmony Ability Packages (HAPs) are application packages that can be installed on OpenHarmony. In this document, the HAPs only refer to the upper-layer applications of the Face_auth driver.
57e41f4b71Sopenharmony_ci
58e41f4b71Sopenharmony_ci- IDL interface
59e41f4b71Sopenharmony_ci
60e41f4b71Sopenharmony_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 Fingerprint_auth service and driver. For details, see [IDL](https://gitee.com/openharmony/ability_idl_tool/blob/master/README.md).
61e41f4b71Sopenharmony_ci
62e41f4b71Sopenharmony_ci- IPC
63e41f4b71Sopenharmony_ci
64e41f4b71Sopenharmony_ci  Inter-Process Communication (IPC) implements data exchange between two processes. For details, see [IPC](https://gitee.com/openharmony/communication_ipc/blob/master/README.md).
65e41f4b71Sopenharmony_ci
66e41f4b71Sopenharmony_ci- HDI
67e41f4b71Sopenharmony_ci
68e41f4b71Sopenharmony_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).
69e41f4b71Sopenharmony_ci
70e41f4b71Sopenharmony_ci### Working Principles
71e41f4b71Sopenharmony_ci
72e41f4b71Sopenharmony_ciThe fingerprint_auth driver provides stable basic fingerprint authentication capabilities for the upper-layer User_auth framework and Fingerprint_auth service to ensure successful fingerprint authentication on devices. The figure below shows the interaction between the Fingerprint_auth service and the Fingerprint_auth driver. The Fingerprint_auth service obtains executor information by using **GetExecutorInfo()** and registers the executor with the User_auth framework. The Fingerprint_auth service exchanges information with the Fingerprint_auth driver for authentication, identification, and query through the executor APIs.
73e41f4b71Sopenharmony_ciYou can develop drivers to call Hardware Device Interface (HDI) APIs based on the HDF and the chip you use.
74e41f4b71Sopenharmony_ci
75e41f4b71Sopenharmony_ci**Figure 2** Interaction between the Fingerprint_auth service and Fingerprint_auth driver
76e41f4b71Sopenharmony_ci
77e41f4b71Sopenharmony_ci![image](figures/fingerprint_auth_service_and_driver_interaction.png "Fingerprint_auth service and driver interaction")
78e41f4b71Sopenharmony_ci
79e41f4b71Sopenharmony_ci### Constraints
80e41f4b71Sopenharmony_ci
81e41f4b71Sopenharmony_ciA Trusted Execution Environment (TEE) must be available on the device to store encrypted fingerprint feature information.
82e41f4b71Sopenharmony_ci
83e41f4b71Sopenharmony_ci## Development Guidelines
84e41f4b71Sopenharmony_ci
85e41f4b71Sopenharmony_ci### When to Use
86e41f4b71Sopenharmony_ci
87e41f4b71Sopenharmony_ciThe fingerprint_auth driver provides stable basic fingerprint authentication capabilities for the upper-layer User_auth framework and Fingerprint_auth service to ensure successful fingerprint authentication on devices. To implement the preceding functions, you need to develop the Fingerprint_auth driver based on the HDF, and then implement the APIs for obtaining the executor list and functional APIs such as authentication and query.
88e41f4b71Sopenharmony_ci
89e41f4b71Sopenharmony_ci### Available APIs
90e41f4b71Sopenharmony_ci
91e41f4b71Sopenharmony_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/fingerprint_auth/**.
92e41f4b71Sopenharmony_ci**Table 1** describes the HDI APIs for fingerprint credential enrollment, authentication, recognition, and deletion. **Table 2** describes the callbacks used to return the executor operation result to the framework or return the authentication tip information to upper-layer applications.
93e41f4b71Sopenharmony_ci
94e41f4b71Sopenharmony_ci**Table 1** Available APIs
95e41f4b71Sopenharmony_ci
96e41f4b71Sopenharmony_ci| API       | Description        |
97e41f4b71Sopenharmony_ci| -------------------------------- | ----------------------------------- |
98e41f4b71Sopenharmony_ci| GetExecutorList(std::vector\<sptr\<IAllInOneExecutor>>& allInOneExecutors) | Obtains the executor list of V2_0. |
99e41f4b71Sopenharmony_ci| GetExecutorInfo(ExecutorInfo &executorInfo) | Obtains the executor information, including the executor type, executor role, authentication type, security level, and executor public key. |
100e41f4b71Sopenharmony_ci| OnRegisterFinish(const std::vector\<uint64_t>& templateIdList,<br>        const std::vector\<uint8_t>& frameworkPublicKey, const std::vector\<uint8_t>& extraInfo) | Obtains the public key and template ID list from User_auth after the executor is registered successfully. |
101e41f4b71Sopenharmony_ci| Enroll(uint64_t scheduleId, const std::vector\<uint8_t>& extraInfo,<br>        const sptr\<IExecutorCallback>& callbackObj) | Enrolls a fingerprint.                                              |
102e41f4b71Sopenharmony_ci| Authenticate(uint64_t scheduleId, const std::vector\<uint64_t>& templateIdList, bool endAfterFirstFail,<br>const std::vector\<uint8_t>& extraInfo, const sptr\<IExecutorCallback>& callbackObj) | Authenticates a fingerprint template (V2_0).        |
103e41f4b71Sopenharmony_ci| Identify(uint64_t scheduleId, const std::vector\<uint8_t>& extraInfo,<br>        const sptr\<IExecutorCallback>& callbackObj) | Identifies a fingerprint.          |
104e41f4b71Sopenharmony_ci| Delete(const std::vector\<uint64_t>& templateIdList)          | Deletes a fingerprint.       |
105e41f4b71Sopenharmony_ci| Cancel(uint64_t scheduleId)     | Cancels a fingerprint enrollment, authentication, or identification operation based on the **scheduleId**.    |
106e41f4b71Sopenharmony_ci| SendCommand(int32_t commandId, const std::vector\<uint8_t>& extraInfo,<br>        const sptr\<IExecutorCallback>& callbackObj) | Sends commands to the Fingerprint_auth driver.      |
107e41f4b71Sopenharmony_ci| GetProperty(const std::vector\<uint64_t>& templateIdList,<br>const std::vector\<int32_t>& propertyTypes, Property& property) | Obtains executor property information. |
108e41f4b71Sopenharmony_ci| SetCachedTemplates(const std::vector\<uint64_t\> &templateIdList) | Sets a list of templates to be cached. |
109e41f4b71Sopenharmony_ci| RegisterSaCommandCallback(const sptr\<ISaCommandCallback\> &callbackObj) | Registers a callback to be invoked when an SA command is executed. |
110e41f4b71Sopenharmony_ci
111e41f4b71Sopenharmony_ci**Table 2** Callbacks
112e41f4b71Sopenharmony_ci
113e41f4b71Sopenharmony_ci| API                                                      | Description                |
114e41f4b71Sopenharmony_ci| ------------------------------------------------------------ | ------------------------ |
115e41f4b71Sopenharmony_ci| IExecutorCallback::OnResult(int32_t result, const std::vector\<uint8_t>& extraInfo) | Called to return the operation result.    |
116e41f4b71Sopenharmony_ci| IExecutorCallback::OnTip(int32_t tip, const std::vector\<uint8_t>& extraInfo) | Called to return the interaction information about the operation process. |
117e41f4b71Sopenharmony_ci| ISaCommandCallback::OnSaCommands(const std::vector\<SaCommand>& commands) | Called to send the command list. |
118e41f4b71Sopenharmony_ci
119e41f4b71Sopenharmony_ci### How to Develop
120e41f4b71Sopenharmony_ci
121e41f4b71Sopenharmony_ciThe following uses the Hi3516D V300 development board as an example to demonstrate how to develop the Fingerprint_auth driver. <br/>The directory structure is as follows:
122e41f4b71Sopenharmony_ci
123e41f4b71Sopenharmony_ci```undefined
124e41f4b71Sopenharmony_ci// drivers/peripheral/fingerprint_auth
125e41f4b71Sopenharmony_ci├── BUILD.gn     # Build script
126e41f4b71Sopenharmony_ci├── bundle.json # Component description file
127e41f4b71Sopenharmony_ci└── hdi_service # Fingerprint_auth driver implementation
128e41f4b71Sopenharmony_ci    ├── BUILD.gn     # Build script
129e41f4b71Sopenharmony_ci    ├── include     # Header files
130e41f4b71Sopenharmony_ci    └── src         # Source files
131e41f4b71Sopenharmony_ci        ├── executor_impl.cpp                # Implementation of authentication and enrollment APIs
132e41f4b71Sopenharmony_ci        ├── fingerprint_auth_interface_driver.cpp # Fingerprint_auth driver entry
133e41f4b71Sopenharmony_ci        └── fingerprint_auth_interface_service.cpp # Implementation of the API for obtaining the executor list
134e41f4b71Sopenharmony_ci```
135e41f4b71Sopenharmony_ci
136e41f4b71Sopenharmony_ciThe development procedure is as follows:
137e41f4b71Sopenharmony_ci
138e41f4b71Sopenharmony_ci1. Develop the Fingerprint_auth driver based on the HDF using the **Bind()**, **Init()**, **Release()**, and **Dispatch()** functions. For details about the code, see [fingerprint_auth_interface_driver.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/fingerprint_auth/hdi_service/src/fingerprint_auth_interface_driver.cpp).<br>The sample code is as follows:
139e41f4b71Sopenharmony_ci
140e41f4b71Sopenharmony_ci   ```c++
141e41f4b71Sopenharmony_ci   // Create an IRemoteObject object by using the custom HdfFingerprintAuthInterfaceHost object, which consists of the IoService object and HDI service.
142e41f4b71Sopenharmony_ci   struct HdfFingerprintAuthInterfaceHost {
143e41f4b71Sopenharmony_ci       struct IDeviceIoService ioService;
144e41f4b71Sopenharmony_ci       OHOS::sptr<OHOS::IRemoteObject> stub;
145e41f4b71Sopenharmony_ci   };
146e41f4b71Sopenharmony_ci
147e41f4b71Sopenharmony_ci   // Enable the IPC service to call the response API.
148e41f4b71Sopenharmony_ci   static int32_t FingerprintAuthInterfaceDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data,
149e41f4b71Sopenharmony_ci       struct HdfSBuf *reply)
150e41f4b71Sopenharmony_ci   {
151e41f4b71Sopenharmony_ci       auto *hdfFingerprintAuthInterfaceHost = CONTAINER_OF(client->device->service, struct HdfFingerprintAuthInterfaceHost, ioService);
152e41f4b71Sopenharmony_ci
153e41f4b71Sopenharmony_ci       OHOS::MessageParcel *dataParcel = nullptr;
154e41f4b71Sopenharmony_ci       OHOS::MessageParcel *replyParcel = nullptr;
155e41f4b71Sopenharmony_ci       OHOS::MessageOption option;
156e41f4b71Sopenharmony_ci
157e41f4b71Sopenharmony_ci       if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) {
158e41f4b71Sopenharmony_ci           HDF_LOGE("%{public}s: invalid data sbuf object to dispatch", __func__);
159e41f4b71Sopenharmony_ci           return HDF_ERR_INVALID_PARAM;
160e41f4b71Sopenharmony_ci       }
161e41f4b71Sopenharmony_ci       if (SbufToParcel(reply, &replyParcel) != HDF_SUCCESS) {
162e41f4b71Sopenharmony_ci           HDF_LOGE("%{public}s: invalid reply sbuf object to dispatch", __func__);
163e41f4b71Sopenharmony_ci           return HDF_ERR_INVALID_PARAM;
164e41f4b71Sopenharmony_ci       }
165e41f4b71Sopenharmony_ci
166e41f4b71Sopenharmony_ci       return hdfFingerprintAuthInterfaceHost->stub->SendRequest(cmdId, *dataParcel, *replyParcel, option);
167e41f4b71Sopenharmony_ci   }
168e41f4b71Sopenharmony_ci
169e41f4b71Sopenharmony_ci   // Initialize the HdfFingerprintAuthInterfaceDriver object.
170e41f4b71Sopenharmony_ci   static int HdfFingerprintAuthInterfaceDriverInit(struct HdfDeviceObject *deviceObject)
171e41f4b71Sopenharmony_ci   {
172e41f4b71Sopenharmony_ci       HDF_LOGI("%{public}s: driver init start", __func__);
173e41f4b71Sopenharmony_ci       return HDF_SUCCESS;
174e41f4b71Sopenharmony_ci   }
175e41f4b71Sopenharmony_ci
176e41f4b71Sopenharmony_ci   // Bind the service provided by the Fingerprint_auth driver to the HDF.
177e41f4b71Sopenharmony_ci   static int HdfFingerprintAuthInterfaceDriverBind(struct HdfDeviceObject *deviceObject)
178e41f4b71Sopenharmony_ci   {
179e41f4b71Sopenharmony_ci       HDF_LOGI("%{public}s: driver bind start", __func__);
180e41f4b71Sopenharmony_ci       auto *hdfFingerprintAuthInterfaceHost = new (std::nothrow) HdfFingerprintAuthInterfaceHost;
181e41f4b71Sopenharmony_ci       if (hdfFingerprintAuthInterfaceHost == nullptr) {
182e41f4b71Sopenharmony_ci           HDF_LOGE("%{public}s: failed to create create HdfFingerprintAuthInterfaceHost object", __func__);
183e41f4b71Sopenharmony_ci           return HDF_FAILURE;
184e41f4b71Sopenharmony_ci       }
185e41f4b71Sopenharmony_ci
186e41f4b71Sopenharmony_ci       hdfFingerprintAuthInterfaceHost->ioService.Dispatch = FingerprintAuthInterfaceDriverDispatch;
187e41f4b71Sopenharmony_ci       hdfFingerprintAuthInterfaceHost->ioService.Open = NULL;
188e41f4b71Sopenharmony_ci       hdfFingerprintAuthInterfaceHost->ioService.Release = NULL;
189e41f4b71Sopenharmony_ci
190e41f4b71Sopenharmony_ci       auto serviceImpl = OHOS::HDI::FingerprintAuth::V2_0::IFingerprintAuthInterface::Get(true);
191e41f4b71Sopenharmony_ci       if (serviceImpl == nullptr) {
192e41f4b71Sopenharmony_ci           HDF_LOGE("%{public}s: failed to get of implement service", __func__);
193e41f4b71Sopenharmony_ci           delete hdfFingerprintAuthInterfaceHost;
194e41f4b71Sopenharmony_ci           return HDF_FAILURE;
195e41f4b71Sopenharmony_ci       }
196e41f4b71Sopenharmony_ci
197e41f4b71Sopenharmony_ci       hdfFingerprintAuthInterfaceHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl,
198e41f4b71Sopenharmony_ci           OHOS::HDI::FingerprintAuth::V2_0::IFingerprintAuthInterface::GetDescriptor());
199e41f4b71Sopenharmony_ci       if (hdfFingerprintAuthInterfaceHost->stub == nullptr) {
200e41f4b71Sopenharmony_ci           HDF_LOGE("%{public}s: failed to get stub object", __func__);
201e41f4b71Sopenharmony_ci           delete hdfFingerprintAuthInterfaceHost;
202e41f4b71Sopenharmony_ci           return HDF_FAILURE;
203e41f4b71Sopenharmony_ci       }
204e41f4b71Sopenharmony_ci
205e41f4b71Sopenharmony_ci       deviceObject->service = &hdfFingerprintAuthInterfaceHost->ioService;
206e41f4b71Sopenharmony_ci       return HDF_SUCCESS;
207e41f4b71Sopenharmony_ci   }
208e41f4b71Sopenharmony_ci
209e41f4b71Sopenharmony_ci   // Release the resources used by the Fingerprint_auth driver.
210e41f4b71Sopenharmony_ci   static void HdfFingerprintAuthInterfaceDriverRelease(struct HdfDeviceObject *deviceObject)
211e41f4b71Sopenharmony_ci   {
212e41f4b71Sopenharmony_ci       HDF_LOGI("%{public}s: driver release start", __func__);
213e41f4b71Sopenharmony_ci       if (deviceObject->service == nullptr) {
214e41f4b71Sopenharmony_ci           return;
215e41f4b71Sopenharmony_ci       }
216e41f4b71Sopenharmony_ci       auto *hdfFingerprintAuthInterfaceHost = CONTAINER_OF(deviceObject->service, struct HdfFingerprintAuthInterfaceHost, ioService);
217e41f4b71Sopenharmony_ci       if (hdfFingerprintAuthInterfaceHost != nullptr) {
218e41f4b71Sopenharmony_ci           delete hdfFingerprintAuthInterfaceHost;
219e41f4b71Sopenharmony_ci       }
220e41f4b71Sopenharmony_ci   }
221e41f4b71Sopenharmony_ci
222e41f4b71Sopenharmony_ci   // Register the Fingerprint_auth driver entry data structure object.
223e41f4b71Sopenharmony_ci   struct HdfDriverEntry g_fingerprintAuthInterfaceDriverEntry = {
224e41f4b71Sopenharmony_ci       .moduleVersion = 1,
225e41f4b71Sopenharmony_ci       .moduleName = "drivers_peripheral_fingerprint_auth",
226e41f4b71Sopenharmony_ci       .Bind = HdfFingerprintAuthInterfaceDriverBind,
227e41f4b71Sopenharmony_ci       .Init = HdfFingerprintAuthInterfaceDriverInit,
228e41f4b71Sopenharmony_ci       .Release = HdfFingerprintAuthInterfaceDriverRelease,
229e41f4b71Sopenharmony_ci   };
230e41f4b71Sopenharmony_ci
231e41f4b71Sopenharmony_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.
232e41f4b71Sopenharmony_ci   HDF_INIT(g_fingerprintAuthInterfaceDriverEntry);
233e41f4b71Sopenharmony_ci   ```
234e41f4b71Sopenharmony_ci
235e41f4b71Sopenharmony_ci2. Implement the API for obtaining the executor list. For details about the code, see [fingerprint_auth_interface_service.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/fingerprint_auth/hdi_service/src/fingerprint_auth_interface_service.cpp).<br>The sample code is as follows:
236e41f4b71Sopenharmony_ci
237e41f4b71Sopenharmony_ci   ```c++
238e41f4b71Sopenharmony_ci   // Executor implementation class
239e41f4b71Sopenharmony_ci   class AllInOneExecutorImpl : public IAllInOneExecutor {
240e41f4b71Sopenharmony_ci   public:
241e41f4b71Sopenharmony_ci       AllInOneExecutorImpl(struct ExecutorInfo executorInfo);
242e41f4b71Sopenharmony_ci       virtual ~AllInOneExecutorImpl() {}
243e41f4b71Sopenharmony_ci
244e41f4b71Sopenharmony_ci   private:
245e41f4b71Sopenharmony_ci       struct ExecutorInfo executorInfo_; // Executor information
246e41f4b71Sopenharmony_ci   };
247e41f4b71Sopenharmony_ci
248e41f4b71Sopenharmony_ci   static constexpr uint16_t SENSOR_ID = 123; // Executor sensor ID
249e41f4b71Sopenharmony_ci   static constexpr uint32_t EXECUTOR_TYPE = 123; // Executor type
250e41f4b71Sopenharmony_ci   static constexpr size_t PUBLIC_KEY_LEN = 32; //32-byte public key of the executor
251e41f4b71Sopenharmony_ci
252e41f4b71Sopenharmony_ci   // Create an HDI service object.
253e41f4b71Sopenharmony_ci   extern "C" IFingerprintAuthInterface *FingerprintAuthInterfaceImplGetInstance(void)
254e41f4b71Sopenharmony_ci   {
255e41f4b71Sopenharmony_ci       auto fingerprintAuthInterfaceService = new (std::nothrow) FingerprintAuthInterfaceService();
256e41f4b71Sopenharmony_ci       if (fingerprintAuthInterfaceService == nullptr) {
257e41f4b71Sopenharmony_ci           IAM_LOGE("fingerprintAuthInterfaceService is nullptr");
258e41f4b71Sopenharmony_ci           return nullptr;
259e41f4b71Sopenharmony_ci       }
260e41f4b71Sopenharmony_ci       return fingerprintAuthInterfaceService;
261e41f4b71Sopenharmony_ci   }
262e41f4b71Sopenharmony_ci
263e41f4b71Sopenharmony_ci   // Obtain the executor list of V2_0.
264e41f4b71Sopenharmony_ci   int32_t FingerprintAuthInterfaceService::GetExecutorList(std::vector<sptr<IAllInOneExecutor>> &executorList)
265e41f4b71Sopenharmony_ci   {
266e41f4b71Sopenharmony_ci       IAM_LOGI("interface mock start");
267e41f4b71Sopenharmony_ci       for (auto executor : executorList_) {
268e41f4b71Sopenharmony_ci           executorList.push_back(executor);
269e41f4b71Sopenharmony_ci       }
270e41f4b71Sopenharmony_ci       IAM_LOGI("interface mock success");
271e41f4b71Sopenharmony_ci       return HDF_SUCCESS;
272e41f4b71Sopenharmony_ci   }
273e41f4b71Sopenharmony_ci   ```
274e41f4b71Sopenharmony_ci
275e41f4b71Sopenharmony_ci3. Implement each function of the executor. For details about the code, see [all_in_one_executor_impl.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/fingerprint_auth/hdi_service/src/all_in_one_executor_impl.cpp).<br>The sample code is as follows:
276e41f4b71Sopenharmony_ci
277e41f4b71Sopenharmony_ci   ```c++
278e41f4b71Sopenharmony_ci   // Obtain the executor information.
279e41f4b71Sopenharmony_ci   int32_t AllInOneExecutorImpl::GetExecutorInfo(ExecutorInfo &executorInfo)
280e41f4b71Sopenharmony_ci   {
281e41f4b71Sopenharmony_ci       IAM_LOGI("interface mock start");
282e41f4b71Sopenharmony_ci       executorInfo = executorInfo_;
283e41f4b71Sopenharmony_ci       IAM_LOGI("get executor information success");
284e41f4b71Sopenharmony_ci       return HDF_SUCCESS;
285e41f4b71Sopenharmony_ci   }
286e41f4b71Sopenharmony_ci
287e41f4b71Sopenharmony_ci   // After the executor is successfully registered, obtain the public key and template ID list from User_auth and save the public key. The executor compares its template ID list with the template ID list obtained and updates its template ID list.
288e41f4b71Sopenharmony_ci   int32_t AllInOneExecutorImpl::OnRegisterFinish(const std::vector<uint64_t> &templateIdList,
289e41f4b71Sopenharmony_ci       const std::vector<uint8_t> &frameworkPublicKey, const std::vector<uint8_t> &extraInfo)
290e41f4b71Sopenharmony_ci   {
291e41f4b71Sopenharmony_ci       IAM_LOGI("interface mock start");
292e41f4b71Sopenharmony_ci       static_cast<void>(templateIdList);
293e41f4b71Sopenharmony_ci       static_cast<void>(extraInfo);
294e41f4b71Sopenharmony_ci       static_cast<void>(frameworkPublicKey);
295e41f4b71Sopenharmony_ci       IAM_LOGI("register finish");
296e41f4b71Sopenharmony_ci       return HDF_SUCCESS;
297e41f4b71Sopenharmony_ci   }
298e41f4b71Sopenharmony_ci
299e41f4b71Sopenharmony_ci   // Enroll fingerprints.
300e41f4b71Sopenharmony_ci   int32_t AllInOneExecutorImpl::Enroll(
301e41f4b71Sopenharmony_ci       uint64_t scheduleId, const std::vector<uint8_t> &extraInfo, const sptr<IExecutorCallback> &callbackObj)
302e41f4b71Sopenharmony_ci   {
303e41f4b71Sopenharmony_ci       IAM_LOGI("interface mock start");
304e41f4b71Sopenharmony_ci       static_cast<void>(scheduleId);
305e41f4b71Sopenharmony_ci       static_cast<void>(extraInfo);
306e41f4b71Sopenharmony_ci       if (callbackObj == nullptr) {
307e41f4b71Sopenharmony_ci           IAM_LOGE("callbackObj is nullptr");
308e41f4b71Sopenharmony_ci           return HDF_ERR_INVALID_PARAM;
309e41f4b71Sopenharmony_ci       }
310e41f4b71Sopenharmony_ci       IAM_LOGI("enroll, result is %{public}d", ResultCode::OPERATION_NOT_SUPPORT);
311e41f4b71Sopenharmony_ci       int32_t ret = callbackObj->OnResult(ResultCode::OPERATION_NOT_SUPPORT, {});
312e41f4b71Sopenharmony_ci       if (ret != HDF_SUCCESS) {
313e41f4b71Sopenharmony_ci           IAM_LOGE("callback result is %{public}d", ret);
314e41f4b71Sopenharmony_ci           return HDF_FAILURE;
315e41f4b71Sopenharmony_ci       }
316e41f4b71Sopenharmony_ci       return HDF_SUCCESS;
317e41f4b71Sopenharmony_ci   }
318e41f4b71Sopenharmony_ci
319e41f4b71Sopenharmony_ci   // Perform fingerprint authentication.
320e41f4b71Sopenharmony_ci   int32_t AllInOneExecutorService::Authenticate(uint64_t scheduleId, const std::vector<uint64_t> &templateIdList,
321e41f4b71Sopenharmony_ci       const std::vector<uint8_t> &extraInfo, const sptr<IExecutorCallback> &callbackObj)
322e41f4b71Sopenharmony_ci   {
323e41f4b71Sopenharmony_ci       IAM_LOGI("interface mock start");
324e41f4b71Sopenharmony_ci       static_cast<void>(scheduleId);
325e41f4b71Sopenharmony_ci       static_cast<void>(templateIdList);
326e41f4b71Sopenharmony_ci       static_cast<void>(extraInfo);
327e41f4b71Sopenharmony_ci       if (callbackObj == nullptr) {
328e41f4b71Sopenharmony_ci           IAM_LOGE("callbackObj is nullptr");
329e41f4b71Sopenharmony_ci           return HDF_ERR_INVALID_PARAM;
330e41f4b71Sopenharmony_ci       }
331e41f4b71Sopenharmony_ci       IAM_LOGI("authenticate, result is %{public}d", ResultCode::NOT_ENROLLED);
332e41f4b71Sopenharmony_ci       int32_t ret = callbackObj->OnResult(ResultCode::NOT_ENROLLED, {});
333e41f4b71Sopenharmony_ci       if (ret != HDF_SUCCESS) {
334e41f4b71Sopenharmony_ci           IAM_LOGE("callback result is %{public}d", ret);
335e41f4b71Sopenharmony_ci           return HDF_FAILURE;
336e41f4b71Sopenharmony_ci       }
337e41f4b71Sopenharmony_ci       return HDF_SUCCESS;
338e41f4b71Sopenharmony_ci   }
339e41f4b71Sopenharmony_ci
340e41f4b71Sopenharmony_ci   // Identify fingerprints.
341e41f4b71Sopenharmony_ci   int32_t AllInOneExecutorService::Identify(
342e41f4b71Sopenharmony_ci       uint64_t scheduleId, const std::vector<uint8_t> &extraInfo, const sptr<IExecutorCallback> &callbackObj)
343e41f4b71Sopenharmony_ci   {
344e41f4b71Sopenharmony_ci       IAM_LOGI("interface mock start");
345e41f4b71Sopenharmony_ci       static_cast<void>(scheduleId);
346e41f4b71Sopenharmony_ci       static_cast<void>(extraInfo);
347e41f4b71Sopenharmony_ci       if (callbackObj == nullptr) {
348e41f4b71Sopenharmony_ci           IAM_LOGE("callbackObj is nullptr");
349e41f4b71Sopenharmony_ci           return HDF_ERR_INVALID_PARAM;
350e41f4b71Sopenharmony_ci       }
351e41f4b71Sopenharmony_ci       IAM_LOGI("identify, result is %{public}d", ResultCode::OPERATION_NOT_SUPPORT);
352e41f4b71Sopenharmony_ci       int32_t ret = callbackObj->OnResult(ResultCode::OPERATION_NOT_SUPPORT, {});
353e41f4b71Sopenharmony_ci       if (ret != HDF_SUCCESS) {
354e41f4b71Sopenharmony_ci           IAM_LOGE("callback result is %{public}d", ret);
355e41f4b71Sopenharmony_ci           return HDF_FAILURE;
356e41f4b71Sopenharmony_ci       }
357e41f4b71Sopenharmony_ci       return HDF_SUCCESS;
358e41f4b71Sopenharmony_ci   }
359e41f4b71Sopenharmony_ci
360e41f4b71Sopenharmony_ci   // Delete fingerprints.
361e41f4b71Sopenharmony_ci   int32_t AllInOneExecutorService::Delete(const std::vector<uint64_t> &templateIdList)
362e41f4b71Sopenharmony_ci   {
363e41f4b71Sopenharmony_ci       IAM_LOGI("interface mock start");
364e41f4b71Sopenharmony_ci       static_cast<void>(templateIdList);
365e41f4b71Sopenharmony_ci       IAM_LOGI("delete success");
366e41f4b71Sopenharmony_ci       return HDF_SUCCESS;
367e41f4b71Sopenharmony_ci   }
368e41f4b71Sopenharmony_ci
369e41f4b71Sopenharmony_ci   // Cancel the operation based on the specified scheduleId.
370e41f4b71Sopenharmony_ci   int32_t AllInOneExecutorService::Cancel(uint64_t scheduleId)
371e41f4b71Sopenharmony_ci   {
372e41f4b71Sopenharmony_ci       IAM_LOGI("interface mock start");
373e41f4b71Sopenharmony_ci       static_cast<void>(scheduleId);
374e41f4b71Sopenharmony_ci       IAM_LOGI("cancel success");
375e41f4b71Sopenharmony_ci       return HDF_SUCCESS;
376e41f4b71Sopenharmony_ci   }
377e41f4b71Sopenharmony_ci
378e41f4b71Sopenharmony_ci   // Send template locking or unlocking command from the Fingerprint_auth service to the Fingerprint_auth driver.
379e41f4b71Sopenharmony_ci   int32_t AllInOneExecutorService::SendCommand(
380e41f4b71Sopenharmony_ci       int32_t commandId, const std::vector<uint8_t> &extraInfo, const sptr<IExecutorCallback> &callbackObj)
381e41f4b71Sopenharmony_ci   {
382e41f4b71Sopenharmony_ci       IAM_LOGI("interface mock start");
383e41f4b71Sopenharmony_ci       static_cast<void>(extraInfo);
384e41f4b71Sopenharmony_ci       if (callbackObj == nullptr) {
385e41f4b71Sopenharmony_ci           IAM_LOGE("callbackObj is nullptr");
386e41f4b71Sopenharmony_ci           return HDF_ERR_INVALID_PARAM;
387e41f4b71Sopenharmony_ci       }
388e41f4b71Sopenharmony_ci       int32_t ret;
389e41f4b71Sopenharmony_ci       switch (commandId) {
390e41f4b71Sopenharmony_ci           case DriverCommandId::LOCK_TEMPLATE:
391e41f4b71Sopenharmony_ci               IAM_LOGI("lock template, result is %{public}d", ResultCode::SUCCESS);
392e41f4b71Sopenharmony_ci               ret = callbackObj->OnResult(ResultCode::SUCCESS, {});
393e41f4b71Sopenharmony_ci               if (ret != HDF_SUCCESS) {
394e41f4b71Sopenharmony_ci                   IAM_LOGE("callback result is %{public}d", ret);
395e41f4b71Sopenharmony_ci                   return HDF_FAILURE;
396e41f4b71Sopenharmony_ci               }
397e41f4b71Sopenharmony_ci               break;
398e41f4b71Sopenharmony_ci           case DriverCommandId::UNLOCK_TEMPLATE:
399e41f4b71Sopenharmony_ci               IAM_LOGI("unlock template, result is %{public}d", ResultCode::SUCCESS);
400e41f4b71Sopenharmony_ci               ret = callbackObj->OnResult(ResultCode::SUCCESS, {});
401e41f4b71Sopenharmony_ci               if (ret != HDF_SUCCESS) {
402e41f4b71Sopenharmony_ci                   IAM_LOGE("callback result is %{public}d", ret);
403e41f4b71Sopenharmony_ci                   return HDF_FAILURE;
404e41f4b71Sopenharmony_ci               }
405e41f4b71Sopenharmony_ci               break;
406e41f4b71Sopenharmony_ci           case DriverCommandId::INIT_ALGORITHM:
407e41f4b71Sopenharmony_ci               IAM_LOGI("init algorithm, result is %{public}d", ResultCode::SUCCESS);
408e41f4b71Sopenharmony_ci               ret = callbackObj->OnResult(ResultCode::SUCCESS, {});
409e41f4b71Sopenharmony_ci               if (ret != HDF_SUCCESS) {
410e41f4b71Sopenharmony_ci                   IAM_LOGE("callback result is %{public}d", ret);
411e41f4b71Sopenharmony_ci                   return HDF_FAILURE;
412e41f4b71Sopenharmony_ci               }
413e41f4b71Sopenharmony_ci               break;
414e41f4b71Sopenharmony_ci           default:
415e41f4b71Sopenharmony_ci               IAM_LOGD("not support DriverCommandId : %{public}d", commandId);
416e41f4b71Sopenharmony_ci               ret = callbackObj->OnResult(ResultCode::OPERATION_NOT_SUPPORT, {});
417e41f4b71Sopenharmony_ci               if (ret != HDF_SUCCESS) {
418e41f4b71Sopenharmony_ci                   IAM_LOGE("callback result is %{public}d", ret);
419e41f4b71Sopenharmony_ci                   return HDF_FAILURE;
420e41f4b71Sopenharmony_ci               }
421e41f4b71Sopenharmony_ci       }
422e41f4b71Sopenharmony_ci       return HDF_SUCCESS;
423e41f4b71Sopenharmony_ci   }
424e41f4b71Sopenharmony_ci
425e41f4b71Sopenharmony_ci   // Obtain executor properties.
426e41f4b71Sopenharmony_ci   int32_t AllInOneExecutorService::GetProperty(
427e41f4b71Sopenharmony_ci       const std::vector<uint64_t> &templateIdList, const std::vector<int32_t> &propertyTypes, Property &property)
428e41f4b71Sopenharmony_ci   {
429e41f4b71Sopenharmony_ci       IAM_LOGI("interface mock start");
430e41f4b71Sopenharmony_ci       property = {};
431e41f4b71Sopenharmony_ci       IAM_LOGI("get property success");
432e41f4b71Sopenharmony_ci       return HDF_SUCCESS;
433e41f4b71Sopenharmony_ci   }
434e41f4b71Sopenharmony_ci
435e41f4b71Sopenharmony_ci   // Set a list of templates to be cached.
436e41f4b71Sopenharmony_ci   int32_t AllInOneExecutorService::SetCachedTemplates(const std::vector<uint64_t> &templateIdList)
437e41f4b71Sopenharmony_ci   {
438e41f4b71Sopenharmony_ci       IAM_LOGI("interface mock start");
439e41f4b71Sopenharmony_ci       IAM_LOGI("set cached templates success");
440e41f4b71Sopenharmony_ci       return HDF_SUCCESS;
441e41f4b71Sopenharmony_ci   }
442e41f4b71Sopenharmony_ci
443e41f4b71Sopenharmony_ci   // Register the callback to be invoked when the SA command is executed.
444e41f4b71Sopenharmony_ci   int32_t AllInOneExecutorService::RegisterSaCommandCallback(const sptr<ISaCommandCallback> &callbackObj)
445e41f4b71Sopenharmony_ci   {
446e41f4b71Sopenharmony_ci       IAM_LOGI("interface mock start");
447e41f4b71Sopenharmony_ci       IAM_LOGI("register sa command callback success");
448e41f4b71Sopenharmony_ci       return HDF_SUCCESS;
449e41f4b71Sopenharmony_ci   }
450e41f4b71Sopenharmony_ci   ```
451e41f4b71Sopenharmony_ci
452e41f4b71Sopenharmony_ci4. Modify **serviceName2Config** in the **fingerprint_auth_service.cpp** file if you need to add a driver or modify driver information.
453e41f4b71Sopenharmony_ci
454e41f4b71Sopenharmony_ci   ```c++
455e41f4b71Sopenharmony_ci   // base/user_iam/fingerprint_auth/services/src/fingerprint_auth_service.cpp
456e41f4b71Sopenharmony_ci   void FingerprintAuthService::StartDriverManager()
457e41f4b71Sopenharmony_ci   {
458e41f4b71Sopenharmony_ci       IAM_LOGI("start");
459e41f4b71Sopenharmony_ci       int32_t ret = UserAuth::IDriverManager::Start(HDI_NAME_2_CONFIG);
460e41f4b71Sopenharmony_ci       if (ret != UserAuth::ResultCode::SUCCESS) {
461e41f4b71Sopenharmony_ci           IAM_LOGE("start driver manager failed");
462e41f4b71Sopenharmony_ci       }
463e41f4b71Sopenharmony_ci   }
464e41f4b71Sopenharmony_ci   ```
465e41f4b71Sopenharmony_ci
466e41f4b71Sopenharmony_ci### Verification
467e41f4b71Sopenharmony_ci
468e41f4b71Sopenharmony_ciUse the [User Authentication APIs](../../application-dev/reference/apis-user-authentication-kit/js-apis-useriam-userauth.md) to develop a HAP and verify the application on the RK3568 platform. The sample code for starting and canceling an authentication is as follows:
469e41f4b71Sopenharmony_ci
470e41f4b71Sopenharmony_ci1. Initiate a request for user authentication and obtain the authentication result.
471e41f4b71Sopenharmony_ci
472e41f4b71Sopenharmony_ci```ts
473e41f4b71Sopenharmony_ci  // API version 10
474e41f4b71Sopenharmony_ci  import type {BusinessError} from '@ohos.base';
475e41f4b71Sopenharmony_ci  import userIAM_userAuth from '@ohos.userIAM.userAuth';
476e41f4b71Sopenharmony_ci  
477e41f4b71Sopenharmony_ci  // Set authentication parameters.
478e41f4b71Sopenharmony_ci  const authParam: userIAM_userAuth.AuthParam = {
479e41f4b71Sopenharmony_ci    challenge: new Uint8Array([49, 49, 49, 49, 49, 49]),
480e41f4b71Sopenharmony_ci    authType: [userIAM_userAuth.UserAuthType.PIN, userIAM_userAuth.UserAuthType.FINGERPRINT],
481e41f4b71Sopenharmony_ci    authTrustLevel: userIAM_userAuth.AuthTrustLevel.ATL3,
482e41f4b71Sopenharmony_ci  };
483e41f4b71Sopenharmony_ci
484e41f4b71Sopenharmony_ci  // Set the authentication page.
485e41f4b71Sopenharmony_ci  const widgetParam: userIAM_userAuth.WidgetParam = {
486e41f4b71Sopenharmony_ci    title: 'Verify identity',
487e41f4b71Sopenharmony_ci  };
488e41f4b71Sopenharmony_ci
489e41f4b71Sopenharmony_ci  try {
490e41f4b71Sopenharmony_ci    // Obtain an authentication object.
491e41f4b71Sopenharmony_ci    let userAuthInstance = userIAM_userAuth.getUserAuthInstance(authParam, widgetParam);
492e41f4b71Sopenharmony_ci    console.info('get userAuth instance success');
493e41f4b71Sopenharmony_ci    // Subscribe to the authentication result.
494e41f4b71Sopenharmony_ci    userAuthInstance.on('result', {
495e41f4b71Sopenharmony_ci      onResult(result) {
496e41f4b71Sopenharmony_ci        console.info(`userAuthInstance callback result: ${JSON.stringify(result)}`);
497e41f4b71Sopenharmony_ci        // Unsubscribe from the authentication result if required.
498e41f4b71Sopenharmony_ci        userAuthInstance.off('result');
499e41f4b71Sopenharmony_ci      }
500e41f4b71Sopenharmony_ci    });
501e41f4b71Sopenharmony_ci    console.info('auth on success');
502e41f4b71Sopenharmony_ci    userAuthInstance.start();
503e41f4b71Sopenharmony_ci    console.info('auth start success');
504e41f4b71Sopenharmony_ci  } catch (error) {
505e41f4b71Sopenharmony_ci    const err: BusinessError = error as BusinessError;
506e41f4b71Sopenharmony_ci    console.error(`auth catch error. Code is ${err?.code}, message is ${err?.message}`);
507e41f4b71Sopenharmony_ci  }
508e41f4b71Sopenharmony_ci```
509e41f4b71Sopenharmony_ci    
510e41f4b71Sopenharmony_ci2. Cancel an authentication.
511e41f4b71Sopenharmony_ci
512e41f4b71Sopenharmony_ci```ts
513e41f4b71Sopenharmony_ci  // API version 10
514e41f4b71Sopenharmony_ci  import type {BusinessError} from '@ohos.base';
515e41f4b71Sopenharmony_ci  import userIAM_userAuth from '@ohos.userIAM.userAuth';
516e41f4b71Sopenharmony_ci  
517e41f4b71Sopenharmony_ci  const authParam: userIAM_userAuth.AuthParam = {
518e41f4b71Sopenharmony_ci    challenge: new Uint8Array([49, 49, 49, 49, 49, 49]),
519e41f4b71Sopenharmony_ci    authType: [userIAM_userAuth.UserAuthType.PIN, userIAM_userAuth.UserAuthType.FINGERPRINT],
520e41f4b71Sopenharmony_ci    authTrustLevel: userIAM_userAuth.AuthTrustLevel.ATL3,
521e41f4b71Sopenharmony_ci  };
522e41f4b71Sopenharmony_ci
523e41f4b71Sopenharmony_ci  const widgetParam: userIAM_userAuth.WidgetParam = {
524e41f4b71Sopenharmony_ci    title: 'Verify identity',
525e41f4b71Sopenharmony_ci  };
526e41f4b71Sopenharmony_ci  
527e41f4b71Sopenharmony_ci  try {
528e41f4b71Sopenharmony_ci    // Obtain an authentication object.
529e41f4b71Sopenharmony_ci    let userAuthInstance = userIAM_userAuth.getUserAuthInstance(authParam, widgetParam);
530e41f4b71Sopenharmony_ci    console.info('get userAuth instance success');
531e41f4b71Sopenharmony_ci    // Start user authentication.
532e41f4b71Sopenharmony_ci    userAuthInstance.start();
533e41f4b71Sopenharmony_ci    console.info('auth start success');
534e41f4b71Sopenharmony_ci    // Cancel the authentication.
535e41f4b71Sopenharmony_ci    userAuthInstance.cancel();
536e41f4b71Sopenharmony_ci    console.info('auth cancel success');
537e41f4b71Sopenharmony_ci  } catch (error) {
538e41f4b71Sopenharmony_ci    const err: BusinessError = error as BusinessError;
539e41f4b71Sopenharmony_ci    console.error(`auth catch error. Code is ${err?.code}, message is ${err?.message}`);
540e41f4b71Sopenharmony_ci  }
541e41f4b71Sopenharmony_ci```
542