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 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 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