1# Pin_auth
2
3## 概述
4
5### 功能简介
6
7口令认证是端侧设备不可或缺的一部分,为设备提供一种用户认证能力,可应用于设备解锁、支付、应用登录等身份认证场景。用户注册口令后,口令认证模块就可为设备提供密码解锁的功能,保证设备的安全使用。口令识别的整体架构如图1。
8
9基于HDF(Hardware Driver Foundation)驱动框架开发的Pin_auth驱动,Pin_auth驱动模型屏蔽硬件差异,为上层用户IAM子系统基础框架和口令认证SA提供稳定的口令认证基础能力,包括口令认证执行器列表查询、执行器信息查询、指定模板防暴信息查询、用户认证和执行器间的模板信息对账,以及口令的录入、认证、删除。
10
11**图1** 口令认证架构图
12
13![image](figures/口令认证架构图.png "口令认证架构图")
14
15### 基本概念
16用户认证框架与各个基础认证服务(包含口令认证、人脸识别等)组成的身份认证系统,支持用户认证凭据设置、删除、认证等基础功能。
17
18- 执行器
19
20  执行器是能够提供数据采集、处理、存储及比对能力的模块,各基础认证服务提供执行器能力,被身份认证框架调度完成各项基础能力。
21
22- 执行器安全等级
23
24  执行器提供能力时所在运行环境达到的安全级别。
25
26- 执行器角色
27
28  - ​    全功能执行器:执行器可独立处理一次凭据注册和身份认证请求,即可提供用户认证数据采集、处理、储存及比对能力。
29
30  - ​    采集器:执行器提供用户认证时的数据采集能力,需要和认证器配合完成用户认证。
31
32  - ​    认证器:认证器提供用户认证时的数据处理能力,读取存储的凭据模板与当前认证信息完成对比。
33
34- 执行器类型
35
36  同一种身份认证类型的不同认证方式会产生认证算法差异,设备器件差异也会导致算法差异,执行器根据支持的算法类型差异或对接的器件差异,会定义不同的执行器类型。
37
38- 用户认证框架公钥 & 执行器公钥
39
40  用户身份认证处理需要保证用户数据安全以及认证结果的准确性,用户认证框架与基础认证服务间的关键交互信息需要做数据完整性保护,各基础认证服务将提供的执行器能力对接到用户认证框架时,需要交换各自的公钥,其中:
41
42    - 执行器通过用户认证框架公钥校验调度指令的准确性。
43
44    - 执行器公钥可被用户认证框架用于校验认证结果的准确性,同时用于执行器交互认证时的校验交互信息的完整性。
45
46
47- 口令认证凭据模板
48
49  认证凭据是在用户设置认证凭据时由认证服务产生并存储,每个模板有一个ID,用于索引模板信息文件,在认证时读取模板信息并用于与当次认证过程中产生的认证数据做对比,完成身份认证。
50
51- 执行器对账
52
53  用户认证框架统一管理用户身份和凭据ID的映射关系,执行器对接到用户认证框架时,会读取用户身份认证框架内保存的该执行器的模板ID列表,执行器需要与自己维护的模板ID列表进行比对,并删除冗余信息。
54
55- IDL接口
56
57  接口定义语言(Interface Definition Language)通过IDL编译器编译后,能够生成与编程语言相关的文件:客户端桩文件,服务器框架文件。本文主要是通过IDL接口生成的客户端和服务端来实现Pin_auth服务和驱动的通信,详细使用方法可参考[IDL简介](https://gitee.com/openharmony/ability_idl_tool/blob/master/README.md)58
59- IPC通信
60
61  IPC(Inter Process Communication),进程间通信是指两个进程的数据之间产生交互,详细原理可参考[IPC通信简介](https://gitee.com/openharmony/communication_ipc/blob/master/README_zh.md)62
63- HDI
64
65  HDI(Hardware Device Interface),硬件设备接口,位于基础系统服务层和设备驱动层之间,是提供给硬件系统服务开发者使用的、统一的硬件设备功能抽象接口,其目的是为系统服务屏蔽底层硬件设备差异,具体可参考[HDI规范](../../design/hdi-design-specifications.md)。
66
67### 运作机制
68
69Pin_auth驱动的主要工作是为上层用户认证框架和Pin_auth服务提供稳定的口令认证的基础能力,保证口令认证的功能可以正常运行。开发者可基于HDF框架对不同芯片进行各自驱动的开发以及HDI层接口的调用。
70
71**图2** Pin_auth服务和pin_auth驱动接口
72
73![image](figures/pin_auth服务与驱动交互.png "pin_auth服务与驱动交互")
74
75### 约束与限制
76口令认证的实现需要在TEE安全环境中实现,口令凭据等数据的加密信息需要在安全环境中存储。
77## 开发指导
78
79### 场景介绍
80Pin_auth驱动的主要工作是为上层用户认证框架和Pin_auth服务提供稳定的口令认证基础能力,保证设备上口令认证功能可以正常运行。
81
82### 接口说明
83
84注:以下接口列举的为IDL接口描述生成的对应C++语言函数接口,接口声明见idl文件(/drivers/interface/pin_auth)。
85在本文中,口令凭据的录入、认证和删除相关的HDI接口如表1所示,表2中的回调函数分别用于口令执行器返回操作结果给框架和获取用户输入的口令信息。
86
87**表1** 接口功能介绍
88
89|    接口名称    |   功能介绍   |
90| ------------------------------- | ------------------------------------------- |
91| GetExecutorInfo(ExecutorInfo& executorInfo)  | 获取执行器信息。 |
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)  | 获取V2_0执行器列表。 |
93| OnRegisterFinish(const std::vector<uint64_t>& templateIdList,<br/>const std::vector<uint8_t>& frameworkPublicKey,<br/>const std::vector<uint8_t>&  extraInfo) | 执行器注册成功后,获取用户认证框架的公钥信息;获取用户认证框架的template 列表用于对账。 |
94| Cancel(uint64_t scheduleId) | 通过scheduleId取消指定操作。       |
95| SetData(uint64_t scheduleId, uint64_t authSubType, <br/>const std::vector<uint8_t> &data, int32_t resultCode) | 回调函数,返回用户录入的口令子类型和录入的口令脱敏数据。       |
96| Enroll(uint64_t scheduleId, const std::vector<uint8_t>& extraInfo, <br/>const sptr<IExecutorCallback>& callbackObj) | 录入pin码。      |
97| Authenticate(uint64_t scheduleId, const std::vector<uint64_t>& templateIdList, const std::vector<uint8_t>& extraInfo, const sptr<IExecutorCallback>& callbackObj) | pin码认证。      |
98| Delete(uint64_t templateId)       | 删除pin码模板。       |
99| GetProperty(const std::vector<uint64_t>& templateIdList, <br/>const std::vector<GetPropertyType>& propertyTypes, Property& property) | 获取执行器属性信息。 |
100
101
102**表2** 回调函数介绍
103
104| 接口名称                                                       | 功能介绍             |
105| ------------------------------------------------------------ | -------------------- |
106| IExecutorCallback::OnResult(int32_t result, const std::vector<uint8_t>& extraInfo) | 返回操作的最终结果。 |
107| IExecutorCallback::OnTip(int32_t tip, const std::vector<uint8_t>& extraInfo) | 返回操作的过程提示信息。 |
108| IExecutorCallback::OnGetData(const std::vector<uint8_t>& algoParameter, uint64_t authSubType, uint32_t algoVersion, const std::vector<uint8_t>& challenge)| 返回获取pin码数据信息。  |
109| IExecutorCallback::OnMessage(int32_t destRole, const std::vector<uint8_t>& msg)| 返回操作的过程交互消息。  |
110
111### 开发步骤
112
113以RK3568平台为例,我们提供了Pin_auth驱动DEMO实例,以下是目录结构及各部分功能简介。
114
115```text
116// drivers/peripheral/pin_auth
117├── BUILD.gn     # 编译脚本
118├── bundle.json  # 组件描述文件
119├── test         # 测试用例
120└── hdi_service  # Pin_auth驱动实现
121    ├── BUILD.gn   # 编译脚本
122    ├── adaptor    # 相关算法实现
123    ├── common     # 公共接口实现
124    ├── database   # 数据库实现
125    ├── main       # 口令相关功能实现入口
126    └── service    # Pin_auth驱动实现入口
127        ├── inc      # 头文件
128        └── src      # 源文件
129            ├── all_in_one_impl.cpp             # 全功能执行器认证、录入等功能接口实现
130            ├── verifier_impl.cpp               # 认证器认证、录入等功能接口实现
131            ├── collector_impl.cpp              # 采集器认证、录入等功能接口实现
132            ├── executor_impl_common.cpp        # 工具类
133            ├── pin_auth_interface_driver.cpp   # Pin_auth驱动入口
134            └── pin_auth_interface_service.cpp  # 获取执行器列表接口实现
135```
136
137
138下面结合DEMO实例介绍驱动开发的具体步骤。
139
1401. 基于HDF驱动框架,按照驱动Driver Entry程序,完成pin_auth驱动开发,主要由Bind、Init、Release、Dispatch函数接口实现,详细代码参见[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   // 通过自定义的HdfPinAuthInterfaceHost对象包含IoService对象和真正的HDI Service实现PinAuthInterfaceService对象
144   struct HdfPinAuthInterfaceHost {
145       struct IDeviceIoService ioService;
146       OHOS::sptr<OHOS::IRemoteObject> stub;
147   };
148
149   // 服务接口调用响应接口
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   // 初始化接口
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   // PinAuth驱动对外提供的服务绑定到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   // 释放PinAuth驱动中的资源
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   // 调用HDF_INIT将驱动入口注册到HDF框架中,在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出
237   HDF_INIT(g_pinauthinterfaceDriverEntry);
238   ```
239
240
241
2422. 完成获取执行器列表接口实现,详细代码参见[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   // 执行器实现类
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   // 获取执行器列表实现,创建执行器(仅作示例)
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. 完成执行器每个功能接口实现,详细代码参见[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   // 实现获取执行器信息接口(仅作示例)
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   // 实现执行器注册成功后,获取用户认证框架的公钥信息、获取用户认证框架的template 列表接口,将公钥信息保存,template列表用于和本地的template做对账
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   // 实现口令录入接口
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 enroll 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   // 实现回调数据获取的接口
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 the scheduleMap_ when the enroll 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   // 实现口令认证接口
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   // 实现删除口令模板接口
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   // 实现通过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   // 获取执行器属性信息接口
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### 调测验证
568驱动开发完成后,可基于RK3568平台验证, 通过设备的设置和锁屏功能验证口令认证功能是否正常,测试步骤如下:
569
5701.  点击设备的 “ 设置 > 生物识别和密码 > 锁屏密码" 后,录入锁屏密码。
5712.  按设备电源键进行锁屏,再次按设备的电源键进行解锁,输入锁屏密码进行解锁验证,至此就完成了口令的录入和认证功能。
5723.  进入设置中的生物识别和密码,点击关闭锁屏密码或者更改锁屏密码,来验证口令的删除和更新功能是否正常。
5734.  在步骤1完成后,进行步骤2的输入锁屏密码时,输入错误密码达到一定的次数来验证,防暴力破解能力是否正常(例如:连续输入5次错误密码,设备将被冻结60s)。
574