• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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| GetExecutorList(std::vector\<sptr\<V1_0::IExecutor>>& executorList)  | 获取V1_0执行器列表。 |
92| GetExecutorListV1_1(std::vector\<sptr\<V1_1::IExecutor>>& executorList)      | 获取V1_1版本执行器列表。                         |
93| GetTemplateInfo(uint64_t templateId, TemplateInfo& info)  | 获取指定templateId的模板信息。   |
94| OnRegisterFinish(const std::vector\<uint64_t>& templateIdList,<br/>const std::vector\<uint8_t>& frameworkPublicKey,<br/>const std::vector\<uint8_t>&  extraInfo) | 执行器注册成功后,获取用户认证框架的公钥信息;获取用户认证框架的template 列表用于对账。 |
95| OnSetData(uint64_t scheduleId, uint64_t authSubType, <br/>const std::vector\<uint8_t> &data) | 回调函数,返回用户录入的口令子类型和录入的口令脱敏数据。       |
96| Enroll(uint64_t scheduleId, const std::vector\<uint8_t>& extraInfo,<br/>const sptr\<IExecutorCallback>& callbackObj) | 录入pin码。      |
97| Authenticate(uint64_t scheduleId, uint64_t templateId, const std::vector\<uint8_t>& extraInfo, const sptr\<IExecutorCallback>& callbackObj) | pin码认证。      |
98| Delete(uint64_t templateId)       | 删除pin码模板。       |
99| Cancel(uint64_t scheduleId)     | 通过scheduleId取消指定操作。  |
100| SendCommand(int32_t commandId, const std::vector\<uint8_t>& extraInfo,<br/>const sptr\<IExecutorCallback>& callbackObj) | 预留接口。  |
101| GetProperty(const std::vector\<uint64_t>& templateIdList,<br/>const std::vector\<GetPropertyType>& propertyTypes, Property& property) | 获取执行器属性信息。 |
102
103
104**表2** 回调函数介绍
105
106| 接口名称                                                       | 功能介绍             |
107| ------------------------------------------------------------ | -------------------- |
108| IExecutorCallback::OnResult(int32_t code, const std::vector\<uint8_t>& extraInfo) | 返回操作的最终结果。 |
109| IExecutorCallback::OnGetData(uint64_t scheduleId, const std::vector\<uint8_t>& salt,<br/> uint64_t authSubType)| 返回获取pin码数据信息。  |
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            ├── executor_impl.cpp               # 认证、录入等功能接口实现
130            ├── pin_auth_interface_driver.cpp   # Pin_auth驱动入口
131            └── pin_auth_interface_service.cpp  # 获取执行器列表接口实现
132```
133
134下面结合DEMO实例介绍驱动开发的具体步骤。
135
1361. 基于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)文件。
137
138   ```c++
139   // 通过自定义的HdfPinAuthInterfaceHost对象包含IoService对象和真正的HDI Service实现PinAuthInterfaceService对象
140   struct HdfPinAuthInterfaceHost {
141       struct IDeviceIoService ioService;
142       OHOS::sptr<OHOS::IRemoteObject> stub;
143   };
144
145   // 服务接口调用响应接口
146   static int32_t PinAuthInterfaceDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data,  struct HdfSBuf *reply)
147   {
148       IAM_LOGI("start");
149       auto *hdfPinAuthInterfaceHost = CONTAINER_OF(client->device->service,
150           struct HdfPinAuthInterfaceHost, ioService);
151
152       OHOS::MessageParcel *dataParcel = nullptr;
153       OHOS::MessageParcel *replyParcel = nullptr;
154       OHOS::MessageOption option;
155
156       if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) {
157           IAM_LOGE("%{public}s:invalid data sbuf object to dispatch", __func__);
158           return HDF_ERR_INVALID_PARAM;
159       }
160       if (SbufToParcel(reply, &replyParcel) != HDF_SUCCESS) {
161           IAM_LOGE("%{public}s:invalid reply sbuf object to dispatch", __func__);
162           return HDF_ERR_INVALID_PARAM;
163       }
164
165       return hdfPinAuthInterfaceHost->stub->SendRequest(cmdId, *dataParcel, *replyParcel, option);
166   }
167
168   // 初始化接口
169   static int HdfPinAuthInterfaceDriverInit(struct HdfDeviceObject *deviceObject)
170   {
171       IAM_LOGI("start");
172       std::shared_ptr<OHOS::UserIAM::PinAuth::PinAuth> pinHdi =
173           OHOS::UserIAM::Common::MakeShared<OHOS::UserIAM::PinAuth::PinAuth>();
174       constexpr uint32_t SUCCESS = 0;
175       if (pinHdi == nullptr || pinHdi->Init() != SUCCESS) {
176           IAM_LOGE("Pin hal init failed");
177           return HDF_FAILURE;
178       }
179       return HDF_SUCCESS;
180   }
181
182   // PinAuth驱动对外提供的服务绑定到HDF框架
183   static int HdfPinAuthInterfaceDriverBind(struct HdfDeviceObject *deviceObject)
184   {
185       IAM_LOGI("start");
186       auto *hdfPinAuthInterfaceHost = new (std::nothrow) HdfPinAuthInterfaceHost;
187       if (hdfPinAuthInterfaceHost == nullptr) {
188           IAM_LOGE("%{public}s: failed to create create HdfPinAuthInterfaceHost object", __func__);
189           return HDF_FAILURE;
190       }
191
192       hdfPinAuthInterfaceHost->ioService.Dispatch = PinAuthInterfaceDriverDispatch;
193       hdfPinAuthInterfaceHost->ioService.Open = NULL;
194       hdfPinAuthInterfaceHost->ioService.Release = NULL;
195
196       auto serviceImpl = IPinAuthInterface::Get(true);
197       if (serviceImpl == nullptr) {
198           IAM_LOGE("%{public}s: failed to get of implement service", __func__);
199           return HDF_FAILURE;
200       }
201
202       hdfPinAuthInterfaceHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl,
203           IPinAuthInterface::GetDescriptor());
204       if (hdfPinAuthInterfaceHost->stub == nullptr) {
205           IAM_LOGE("%{public}s: failed to get stub object", __func__);
206           return HDF_FAILURE;
207       }
208
209       deviceObject->service = &hdfPinAuthInterfaceHost->ioService;
210       IAM_LOGI("success");
211       return HDF_SUCCESS;
212   }
213
214   // 释放PinAuth驱动中的资源
215   static void HdfPinAuthInterfaceDriverRelease(struct HdfDeviceObject *deviceObject)
216   {
217       IAM_LOGI("start");
218       auto *hdfPinAuthInterfaceHost = CONTAINER_OF(deviceObject->service,
219           struct HdfPinAuthInterfaceHost, ioService);
220       delete hdfPinAuthInterfaceHost;
221       IAM_LOGI("success");
222   }
223
224   static struct HdfDriverEntry g_pinAuthInterfaceDriverEntry = {
225       .moduleVersion = 1,
226       .moduleName = "pinauth_interface_service",
227       .Bind = HdfPinAuthInterfaceDriverBind,
228       .Init = HdfPinAuthInterfaceDriverInit,
229       .Release = HdfPinAuthInterfaceDriverRelease,
230   };
231
232   // 调用HDF_INIT将驱动入口注册到HDF框架中,在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出
233   HDF_INIT(g_pinauthinterfaceDriverEntry);
234   ```
235
236
237
2381. 完成获取执行器列表接口实现,详细代码参见[pin_auth_interface_service.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/pin_auth/hdi_service/service/src/pin_auth_interface_service.cpp)文件。
239
240   ```c++
241   // 执行器实现类
242   class ExecutorImpl : public V1_1::IExecutor, public NoCopyable {
243   public:
244       explicit ExecutorImpl(std::shared_ptr<OHOS::UserIAM::PinAuth::PinAuth> pinHdi);
245       virtual ~ExecutorImpl() {}
246       int32_t GetExecutorInfo(ExecutorInfo &info) override;
247       int32_t GetTemplateInfo(uint64_t templateId, TemplateInfo &info) override;
248       int32_t OnRegisterFinish(const std::vector<uint64_t> &templateIdList,
249           const std::vector<uint8_t> &frameworkPublicKey, const std::vector<uint8_t> &extraInfo) override;
250       int32_t OnSetData(uint64_t scheduleId, uint64_t authSubType, const std::vector<uint8_t> &data) override;
251       int32_t Enroll(uint64_t scheduleId, const std::vector<uint8_t> &extraInfo,
252           const sptr<IExecutorCallback> &callbackObj) override;
253       int32_t Authenticate(uint64_t scheduleId, uint64_t templateId, const std::vector<uint8_t> &extraInfo,
254           const sptr<IExecutorCallback> &callbackObj) override;
255       int32_t Delete(uint64_t templateId) override;
256       int32_t Cancel(uint64_t scheduleId) override;
257       int32_t SendCommand(int32_t commandId, const std::vector<uint8_t> &extraInfo,
258           const sptr<IExecutorCallback> &callbackObj) override;
259       int32_t GetProperty(const std::vector<uint64_t> &templateIdList, const std::vector<GetPropertyType> &propertyTypes,
260           Property &property) override;
261
262   private:
263       class ScheduleMap {
264       public:
265           uint32_t AddScheduleInfo(const uint64_t scheduleId, const uint32_t commandId,
266               const sptr<IExecutorCallback> callback, const uint64_t templateId, const std::vector<uint8_t> salt);
267           uint32_t GetScheduleInfo(const uint64_t scheduleId, uint32_t &commandId, sptr<IExecutorCallback> &callback,
268               uint64_t &templateId, std::vector<uint8_t> &salt);
269           uint32_t DeleteScheduleId(const uint64_t scheduleId);
270
271       private:
272           struct ScheduleInfo {
273               uint32_t commandId;
274               sptr<IExecutorCallback> callback;
275               uint64_t templateId;
276               std::vector<uint8_t> salt;
277           };
278
279           std::mutex mutex_;
280           std::map<uint64_t, struct ScheduleInfo> scheduleInfo_;
281       };
282
283   private:
284       uint32_t NewSalt(std::vector<uint8_t> &salt);
285       void CallError(const sptr<IExecutorCallback> &callbackObj, const uint32_t errorCode);
286       std::shared_ptr<OHOS::UserIAM::PinAuth::PinAuth> pinHdi_;
287       ScheduleMap scheduleMap_;
288   };
289
290   // 获取V1_1执行器列表实现,创建执行器(仅作示例)
291   int32_t PinAuthInterfaceService::GetExecutorListV1_1(std::vector<sptr<V1_1::IExecutor>> &executorList)
292   {
293       IAM_LOGI("start");
294       std::shared_ptr<OHOS::UserIAM::PinAuth::PinAuth> pinHdi =
295           OHOS::UserIAM::Common::MakeShared<OHOS::UserIAM::PinAuth::PinAuth>();
296       if (pinHdi == nullptr) {
297           IAM_LOGE("Generate pinHdi failed");
298           return HDF_FAILURE;
299       }
300       sptr<IExecutor> executor = new (std::nothrow) ExecutorImpl(pinHdi);
301       if (executor == nullptr) {
302           IAM_LOGE("Generate executor failed");
303           return HDF_FAILURE;
304       }
305       executorList.push_back(executor);
306       IAM_LOGI("end");
307       return HDF_SUCCESS;
308   }
309
310   // 获取V1_0执行器列表实现,使用V1_1版本执行器实现V1_0版本执行器的功能
311   int32_t PinAuthInterfaceService::GetExecutorList(std::vector<sptr<V1_0::IExecutor>> &executorList)
312   {
313       std::vector<sptr<V1_1::IExecutor>> executorListV1_1;
314       int32_t result = GetExecutorListV1_1(executorListV1_1);
315       for (auto &executor : executorListV1_1) {
316           executorList.push_back(executor);
317       }
318       return result;
319   }
320   ```
321
322
323
3241. 完成执行器每个功能接口实现,详细代码参见[executor_impl.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/pin_auth/hdi_service/service/src/executor_impl.cpp)文件。
325
326   ```c++
327   // 实现获取执行器信息接口(仅作示例)
328   int32_t ExecutorImpl::GetExecutorInfo(ExecutorInfo &info)
329   {
330       IAM_LOGI("start");
331       constexpr unsigned short SENSOR_ID = 1;
332       info.sensorId = SENSOR_ID;
333       info.executorType = EXECUTOR_TYPE;
334       info.executorRole = ExecutorRole::ALL_IN_ONE;
335       info.authType = AuthType::PIN;
336       if (pinHdi_ == nullptr) {
337           IAM_LOGE("pinHdi_ is nullptr");
338           return HDF_FAILURE;
339       }
340       uint32_t eslRet = 0;
341       int32_t result = pinHdi_->GetExecutorInfo(info.publicKey, eslRet);
342       if (result != SUCCESS) {
343           IAM_LOGE("Get ExecutorInfo failed, fail code : %{public}d", result);
344           return result;
345       }
346       info.esl = static_cast<ExecutorSecureLevel>(eslRet);
347
348       return HDF_SUCCESS;
349   }
350
351   // 实现获取指定templateId的模板信息接口
352   int32_t ExecutorImpl::GetTemplateInfo(uint64_t templateId, TemplateInfo &info)
353   {
354       IAM_LOGI("start");
355       if (pinHdi_ == nullptr) {
356           IAM_LOGE("pinHdi_ is nullptr");
357           return HDF_FAILURE;
358       }
359       OHOS::UserIAM::PinAuth::PinCredentialInfo infoRet = {};
360       int32_t result = pinHdi_->QueryPinInfo(templateId, infoRet);
361       if (result != SUCCESS) {
362           IAM_LOGE("Get TemplateInfo failed, fail code : %{public}d", result);
363           return result;
364       }
365       /* subType is stored in extraInfo */
366       info.extraInfo.resize(infoRet.subType);
367       if (memcpy_s(&(info.extraInfo[0]), sizeof(infoRet.subType), &(infoRet.subType), sizeof(infoRet.subType)) != EOK) {
368           IAM_LOGE("copy subType to extraInfo fail!");
369           return HDF_FAILURE;
370       }
371
372       info.executorType = EXECUTOR_TYPE;
373       info.remainAttempts = infoRet.remainTimes;
374       info.lockoutDuration = infoRet.freezingTime;
375
376       return HDF_SUCCESS;
377   }
378
379   // 实现执行器注册成功后,获取用户认证框架的公钥信息、获取用户认证框架的template 列表接口,将公钥信息保存,template列表用于和本地的template做对账
380   int32_t ExecutorImpl::OnRegisterFinish(const std::vector<uint64_t> &templateIdList,
381       const std::vector<uint8_t> &frameworkPublicKey, const std::vector<uint8_t> &extraInfo)
382   {
383       IAM_LOGI("start");
384       static_cast<void>(frameworkPublicKey);
385       static_cast<void>(extraInfo);
386       if (pinHdi_ == nullptr) {
387           IAM_LOGE("pinHdi_ is nullptr");
388           return HDF_FAILURE;
389       }
390       int32_t result = pinHdi_->VerifyTemplateData(templateIdList);
391       if (result != SUCCESS) {
392           IAM_LOGE("Verify templateData failed");
393           return result;
394       }
395
396       return HDF_SUCCESS;
397   }
398
399   // 实现口令录入接口
400   int32_t ExecutorImpl::Enroll(uint64_t scheduleId, const std::vector<uint8_t> &extraInfo,
401       const sptr<IExecutorCallback> &callbackObj)
402   {
403       IAM_LOGI("start");
404       if (callbackObj == nullptr) {
405           IAM_LOGE("callbackObj is nullptr");
406           return HDF_FAILURE;
407       }
408       static_cast<void>(extraInfo);
409       std::vector<uint8_t> salt;
410       if (NewSalt(salt) != HDF_SUCCESS) {
411           IAM_LOGE("new salt failed");
412           CallError(callbackObj, HDF_FAILURE);
413           return HDF_FAILURE;
414       }
415       int32_t result = scheduleMap_.AddScheduleInfo(scheduleId, ENROLL_PIN, callbackObj, 0, salt);
416       if (result != HDF_SUCCESS) {
417           IAM_LOGE("Add scheduleInfo failed, fail code : %{public}d", result);
418           CallError(callbackObj, HDF_FAILURE);
419           return result;
420       }
421       result = callbackObj->OnGetData(scheduleId, salt, 0);
422       if (result != SUCCESS) {
423           IAM_LOGE("Enroll Pin failed, fail code : %{public}d", result);
424           // If the enroll fails, delete scheduleId of scheduleMap
425           if (scheduleMap_.DeleteScheduleId(scheduleId) != HDF_SUCCESS) {
426               IAM_LOGI("delete scheduleId failed");
427           }
428           return result;
429       }
430
431       return HDF_SUCCESS;
432   }
433
434   // 实现回调数据获取的接口
435   int32_t ExecutorImpl::OnSetData(uint64_t scheduleId, uint64_t authSubType, const std::vector<uint8_t> &data)
436   {
437       IAM_LOGI("start");
438       if (pinHdi_ == nullptr) {
439           IAM_LOGE("pinHdi_ is nullptr");
440           return HDF_FAILURE;
441       }
442       std::vector<uint8_t> resultTlv;
443       int32_t result = SUCCESS;
444       constexpr uint32_t INVALID_ID = 2;
445       uint32_t commandId = INVALID_ID;
446       sptr<IExecutorCallback> callback = nullptr;
447       uint64_t templateId = 0;
448       std::vector<uint8_t> salt(0, 0);
449       if (scheduleMap_.GetScheduleInfo(scheduleId, commandId, callback, templateId, salt) != HDF_SUCCESS) {
450           IAM_LOGE("Get ScheduleInfo failed, fail code : %{public}d", result);
451           return HDF_FAILURE;
452       }
453       switch (commandId) {
454           case ENROLL_PIN:
455               result = pinHdi_->EnrollPin(scheduleId, authSubType, salt, data, resultTlv);
456               if (result != SUCCESS) {
457                   IAM_LOGE("Enroll Pin failed, fail code : %{public}d", result);
458               }
459               break;
460           case AUTH_PIN:
461               result = pinHdi_->AuthPin(scheduleId, templateId, data, resultTlv);
462               if (result != SUCCESS) {
463                   IAM_LOGE("Auth Pin failed, fail code : %{public}d", result);
464               }
465               break;
466           default:
467               IAM_LOGE("Error commandId");
468       }
469
470       if (callback->OnResult(result, resultTlv) != SUCCESS) {
471           IAM_LOGE("callbackObj Pin failed");
472       }
473       // Delete scheduleId from the scheduleMap_ when the enroll and authentication are successful
474       if (scheduleMap_.DeleteScheduleId(scheduleId) != HDF_SUCCESS) {
475           IAM_LOGI("delete scheduleId failed");
476       }
477
478       return HDF_SUCCESS;
479   }
480   // 实现口令认证接口
481   int32_t ExecutorImpl::Authenticate(uint64_t scheduleId, uint64_t templateId, const std::vector<uint8_t> &extraInfo,
482       const sptr<IExecutorCallback> &callbackObj)
483   {
484       IAM_LOGI("start");
485       if (callbackObj == nullptr) {
486           IAM_LOGE("callbackObj is nullptr");
487           return HDF_FAILURE;
488       }
489       if (pinHdi_ == nullptr) {
490           IAM_LOGE("pinHdi_ is nullptr");
491           CallError(callbackObj, HDF_FAILURE);
492           return HDF_FAILURE;
493       }
494       static_cast<void>(extraInfo);
495       std::vector<uint8_t> salt;
496       int32_t result = pinHdi_->GetSalt(templateId, salt);
497       if (result  != SUCCESS) {
498           IAM_LOGE("get salt failed, fail code : %{public}d", result);
499           CallError(callbackObj, HDF_FAILURE);
500           return result;
501       }
502       result = scheduleMap_.AddScheduleInfo(scheduleId, AUTH_PIN, callbackObj, templateId, salt);
503       if (result != HDF_SUCCESS) {
504           IAM_LOGE("Add scheduleInfo failed, fail code : %{public}d", result);
505           CallError(callbackObj, HDF_FAILURE);
506           return result;
507       }
508       result = callbackObj->OnGetData(scheduleId, salt, 0);
509       if (result != SUCCESS) {
510           IAM_LOGE("Authenticate Pin failed, fail code : %{public}d", result);
511           // If the authentication fails, delete scheduleId of scheduleMap
512           if (scheduleMap_.DeleteScheduleId(scheduleId) != HDF_SUCCESS) {
513               IAM_LOGI("delete scheduleId failed");
514           }
515           return result;
516       }
517
518       return HDF_SUCCESS;
519   }
520
521   // 实现删除口令模板接口
522   int32_t ExecutorImpl::Delete(uint64_t templateId)
523   {
524       IAM_LOGI("start");
525       if (pinHdi_ == nullptr) {
526           IAM_LOGE("pinHdi_ is nullptr");
527           return HDF_FAILURE;
528       }
529       int32_t result = pinHdi_->DeleteTemplate(templateId);
530       if (result != SUCCESS) {
531           IAM_LOGE("Verify templateData failed, fail code : %{public}d", result);
532           return result;
533       }
534
535       return HDF_SUCCESS;
536   }
537
538   // 实现通过scheduleId取消指定操作接口
539   int32_t ExecutorImpl::Cancel(uint64_t scheduleId)
540   {
541       IAM_LOGI("start");
542       if (scheduleMap_.DeleteScheduleId(scheduleId) != HDF_SUCCESS) {
543           IAM_LOGE("scheduleId is not found");
544           return HDF_FAILURE;
545       }
546       return HDF_SUCCESS;
547   }
548
549   // 口令预留接口
550   int32_t ExecutorImpl::SendCommand(int32_t commandId, const std::vector<uint8_t> &extraInfo,
551       const sptr<IExecutorCallback> &callbackObj)
552   {
553       IAM_LOGI("Extension interface, temporarily useless");
554       static_cast<void>(commandId);
555       static_cast<void>(extraInfo);
556       static_cast<void>(callbackObj);
557       return HDF_SUCCESS;
558   }
559
560   // 获取执行器属性信息接口
561   int32_t ExecutorImpl::GetProperty(
562       const std::vector<uint64_t> &templateIdList, const std::vector<GetPropertyType> &propertyTypes, Property &property)
563   {
564       IAM_LOGI("start");
565       if (pinHdi_ == nullptr) {
566           IAM_LOGE("pinHdi_ is nullptr");
567           return HDF_FAILURE;
568       }
569
570       if (templateIdList.size() != 1) {
571           IAM_LOGE("templateIdList size is not 1");
572           return HDF_FAILURE;
573       }
574
575       uint64_t templateId = templateIdList[0];
576       OHOS::UserIam::PinAuth::PinCredentialInfo infoRet = {};
577       int32_t result = pinHdi_->QueryPinInfo(templateId, infoRet);
578       if (result != SUCCESS) {
579           IAM_LOGE("Get TemplateInfo failed, fail code : %{public}d", result);
580           return HDF_FAILURE;
581       }
582
583       property.authSubType = infoRet.subType;
584       property.remainAttempts = infoRet.remainTimes;
585       property.lockoutDuration = infoRet.freezingTime;
586       return HDF_SUCCESS;
587   }
588   ```
589
590
591### 调测验证
592驱动开发完成后,可基于RK3568平台验证, 通过设备的设置和锁屏功能验证口令认证功能是否正常,测试步骤如下:
593
5941.  点击设备的 “ 设置 > 生物识别和密码 > 锁屏密码" 后,录入锁屏密码。
5952.  按设备电源键进行锁屏,再次按设备的电源键进行解锁,输入锁屏密码进行解锁验证,至此就完成了口令的录入和认证功能。
5963.  进入设置中的生物识别和密码,点击关闭锁屏密码或者更改锁屏密码,来验证口令的删除和更新功能是否正常。
5974.  在步骤1完成后,进行步骤2的输入锁屏密码时,输入错误密码达到一定的次数来验证,防暴力破解能力是否正常(例如:连续输入5次错误密码,设备将被冻结60s)。
598