1/* 2 * Copyright (C) 2022-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "signature.h" 17 18#include <securec.h> 19 20#include "config.h" 21#include "dsa_openssl.h" 22#include "ecdsa_openssl.h" 23#include "log.h" 24#include "memory.h" 25#include "params_parser.h" 26#include "signature_spi.h" 27#include "signature_rsa_openssl.h" 28#include "sm2_openssl.h" 29#include "ed25519_openssl.h" 30#include "utils.h" 31 32typedef HcfResult (*HcfSignSpiCreateFunc)(HcfSignatureParams *, HcfSignSpi **); 33typedef HcfResult (*HcfVerifySpiCreateFunc)(HcfSignatureParams *, HcfVerifySpi **); 34 35typedef struct { 36 HcfSign base; 37 38 HcfSignSpi *spiObj; 39 40 char algoName[HCF_MAX_ALGO_NAME_LEN]; 41} HcfSignImpl; 42 43typedef struct { 44 HcfVerify base; 45 46 HcfVerifySpi *spiObj; 47 48 char algoName[HCF_MAX_ALGO_NAME_LEN]; 49} HcfVerifyImpl; 50 51typedef struct { 52 HcfAlgValue algo; 53 54 HcfSignSpiCreateFunc createFunc; 55} HcfSignGenAbility; 56 57typedef struct { 58 HcfAlgValue algo; 59 60 HcfVerifySpiCreateFunc createFunc; 61} HcfVerifyGenAbility; 62 63static const HcfSignGenAbility SIGN_GEN_ABILITY_SET[] = { 64 { HCF_ALG_ECC, HcfSignSpiEcdsaCreate }, 65 { HCF_ALG_RSA, HcfSignSpiRsaCreate }, 66 { HCF_ALG_DSA, HcfSignSpiDsaCreate }, 67 { HCF_ALG_SM2, HcfSignSpiSm2Create }, 68 { HCF_ALG_ECC_BRAINPOOL, HcfSignSpiEcdsaCreate }, 69 { HCF_ALG_ED25519, HcfSignSpiEd25519Create }, 70}; 71 72static const HcfVerifyGenAbility VERIFY_GEN_ABILITY_SET[] = { 73 { HCF_ALG_ECC, HcfVerifySpiEcdsaCreate }, 74 { HCF_ALG_RSA, HcfVerifySpiRsaCreate }, 75 { HCF_ALG_DSA, HcfVerifySpiDsaCreate }, 76 { HCF_ALG_SM2, HcfVerifySpiSm2Create }, 77 { HCF_ALG_ECC_BRAINPOOL, HcfVerifySpiEcdsaCreate }, 78 { HCF_ALG_ED25519, HcfVerifySpiEd25519Create }, 79}; 80 81static HcfSignSpiCreateFunc FindSignAbility(HcfSignatureParams *params) 82{ 83 if (params->operation == HCF_ALG_ONLY_SIGN && params->algo != HCF_ALG_RSA) { 84 LOGE("Algo not support in OnlySign! [Algo]: %d", params->algo); 85 return NULL; 86 } 87 88 for (uint32_t i = 0; i < sizeof(SIGN_GEN_ABILITY_SET) / sizeof(SIGN_GEN_ABILITY_SET[0]); i++) { 89 if (SIGN_GEN_ABILITY_SET[i].algo == params->algo) { 90 return SIGN_GEN_ABILITY_SET[i].createFunc; 91 } 92 } 93 LOGE("Algo not support! [Algo]: %d", params->algo); 94 return NULL; 95} 96 97static HcfVerifySpiCreateFunc FindVerifyAbility(HcfSignatureParams *params) 98{ 99 if (params->operation == HCF_ALG_VERIFY_RECOVER && params->algo != HCF_ALG_RSA) { 100 LOGE("Failed to check recover params!"); 101 return NULL; 102 } 103 104 for (uint32_t i = 0; i < sizeof(VERIFY_GEN_ABILITY_SET) / sizeof(VERIFY_GEN_ABILITY_SET[0]); i++) { 105 if (VERIFY_GEN_ABILITY_SET[i].algo == params->algo) { 106 return VERIFY_GEN_ABILITY_SET[i].createFunc; 107 } 108 } 109 LOGE("Algo not support! [Algo]: %d", params->algo); 110 return NULL; 111} 112 113static void SetKeyTypeDefault(HcfAlgParaValue value, HcfSignatureParams *paramsObj) 114{ 115 switch (value) { 116 case HCF_ALG_ECC_DEFAULT: 117 paramsObj->algo = HCF_ALG_ECC; 118 break; 119 case HCF_ALG_RSA_DEFAULT: 120 paramsObj->algo = HCF_ALG_RSA; 121 break; 122 case HCF_ALG_DSA_DEFAULT: 123 paramsObj->algo = HCF_ALG_DSA; 124 break; 125 case HCF_ALG_SM2_DEFAULT: 126 paramsObj->algo = HCF_ALG_SM2; 127 break; 128 case HCF_ALG_ECC_BRAINPOOL_DEFAULT: 129 paramsObj->algo = HCF_ALG_ECC_BRAINPOOL; 130 break; 131 default: 132 LOGE("Invalid algo %u.", value); 133 break; 134 } 135} 136 137static void SetKeyType(HcfAlgParaValue value, HcfSignatureParams *paramsObj) 138{ 139 switch (value) { 140 case HCF_ALG_ECC_224: 141 case HCF_ALG_ECC_256: 142 case HCF_ALG_ECC_384: 143 case HCF_ALG_ECC_521: 144 paramsObj->algo = HCF_ALG_ECC; 145 break; 146 case HCF_ALG_ECC_BP160R1: 147 case HCF_ALG_ECC_BP160T1: 148 case HCF_ALG_ECC_BP192R1: 149 case HCF_ALG_ECC_BP192T1: 150 case HCF_ALG_ECC_BP224R1: 151 case HCF_ALG_ECC_BP224T1: 152 case HCF_ALG_ECC_BP256R1: 153 case HCF_ALG_ECC_BP256T1: 154 case HCF_ALG_ECC_BP320R1: 155 case HCF_ALG_ECC_BP320T1: 156 case HCF_ALG_ECC_BP384R1: 157 case HCF_ALG_ECC_BP384T1: 158 case HCF_ALG_ECC_BP512R1: 159 case HCF_ALG_ECC_BP512T1: 160 paramsObj->algo = HCF_ALG_ECC_BRAINPOOL; 161 break; 162 case HCF_OPENSSL_RSA_512: 163 case HCF_OPENSSL_RSA_768: 164 case HCF_OPENSSL_RSA_1024: 165 case HCF_OPENSSL_RSA_2048: 166 case HCF_OPENSSL_RSA_3072: 167 case HCF_OPENSSL_RSA_4096: 168 case HCF_OPENSSL_RSA_8192: 169 paramsObj->algo = HCF_ALG_RSA; 170 break; 171 case HCF_ALG_DSA_1024: 172 case HCF_ALG_DSA_2048: 173 case HCF_ALG_DSA_3072: 174 paramsObj->algo = HCF_ALG_DSA; 175 break; 176 case HCF_ALG_SM2_256: 177 paramsObj->algo = HCF_ALG_SM2; 178 break; 179 case HCF_ALG_ED25519_256: 180 paramsObj->algo = HCF_ALG_ED25519; 181 break; 182 default: 183 LOGE("there is not matched algorithm."); 184 break; 185 } 186} 187 188static HcfResult ParseSignatureParams(const HcfParaConfig *config, void *params) 189{ 190 if (config == NULL || params == NULL) { 191 LOGE("Invalid signature params"); 192 return HCF_INVALID_PARAMS; 193 } 194 HcfResult ret = HCF_SUCCESS; 195 HcfSignatureParams *paramsObj = (HcfSignatureParams *)params; 196 LOGD("Set Parameter: %s", config->tag); 197 switch (config->paraType) { 198 case HCF_ALG_TYPE: 199 SetKeyTypeDefault(config->paraValue, paramsObj); 200 break; 201 case HCF_ALG_KEY_TYPE: 202 SetKeyType(config->paraValue, paramsObj); 203 break; 204 case HCF_ALG_DIGEST: 205 paramsObj->md = config->paraValue; 206 break; 207 case HCF_ALG_PADDING_TYPE: 208 paramsObj->padding = config->paraValue; 209 break; 210 case HCF_ALG_MGF1_DIGEST: 211 paramsObj->mgf1md = config->paraValue; 212 break; 213 case HCF_ALG_SIGN_TYPE: 214 paramsObj->operation = config->paraValue; 215 break; 216 case HCF_ALG_VERIFY_TYPE: 217 paramsObj->operation = config->paraValue; 218 break; 219 default: 220 ret = HCF_INVALID_PARAMS; 221 break; 222 } 223 return ret; 224} 225 226static const char *GetSignClass(void) 227{ 228 return "HcfSign"; 229} 230 231static const char *GetVerifyClass(void) 232{ 233 return "HcfVerify"; 234} 235 236static const char *GetSignAlgoName(HcfSign *self) 237{ 238 if (self == NULL) { 239 LOGE("The input self ptr is NULL!"); 240 return NULL; 241 } 242 if (!HcfIsClassMatch((HcfObjectBase *)self, GetSignClass())) { 243 return NULL; 244 } 245 return ((HcfSignImpl *)self)->algoName; 246} 247 248static const char *GetVerifyAlgoName(HcfVerify *self) 249{ 250 if (self == NULL) { 251 LOGE("The input self ptr is NULL!"); 252 return NULL; 253 } 254 if (!HcfIsClassMatch((HcfObjectBase *)self, GetVerifyClass())) { 255 return NULL; 256 } 257 return ((HcfVerifyImpl *)self)->algoName; 258} 259 260static void DestroySign(HcfObjectBase *self) 261{ 262 if (self == NULL) { 263 return; 264 } 265 if (!HcfIsClassMatch(self, GetSignClass())) { 266 LOGE("Class not match."); 267 return; 268 } 269 HcfSignImpl *impl = (HcfSignImpl *)self; 270 HcfObjDestroy(impl->spiObj); 271 impl->spiObj = NULL; 272 HcfFree(impl); 273} 274 275static void DestroyVerify(HcfObjectBase *self) 276{ 277 if (self == NULL) { 278 return; 279 } 280 if (!HcfIsClassMatch(self, GetVerifyClass())) { 281 LOGE("Class not match."); 282 return; 283 } 284 HcfVerifyImpl *impl = (HcfVerifyImpl *)self; 285 HcfObjDestroy(impl->spiObj); 286 impl->spiObj = NULL; 287 HcfFree(impl); 288} 289 290static HcfResult SetSignSpecInt(HcfSign *self, SignSpecItem item, int32_t saltLen) 291{ 292 if (self == NULL) { 293 LOGE("Invalid input parameter."); 294 return HCF_INVALID_PARAMS; 295 } 296 if (!HcfIsClassMatch((HcfObjectBase *)self, GetSignClass())) { 297 LOGE("Class not match."); 298 return HCF_INVALID_PARAMS; 299 } 300 HcfSignImpl *tmpSelf = (HcfSignImpl *)self; 301 return tmpSelf->spiObj->engineSetSignSpecInt(tmpSelf->spiObj, item, saltLen); 302} 303 304static HcfResult GetSignSpecString(HcfSign *self, SignSpecItem item, char **returnString) 305{ 306 if (self == NULL || returnString == NULL) { 307 LOGE("Invalid input parameter."); 308 return HCF_INVALID_PARAMS; 309 } 310 if (!HcfIsClassMatch((HcfObjectBase *)self, GetSignClass())) { 311 LOGE("Class not match."); 312 return HCF_INVALID_PARAMS; 313 } 314 HcfSignImpl *tmpSelf = (HcfSignImpl *)self; 315 return tmpSelf->spiObj->engineGetSignSpecString(tmpSelf->spiObj, item, returnString); 316} 317 318static HcfResult SetSignSpecUint8Array(HcfSign *self, SignSpecItem item, HcfBlob blob) 319{ 320 if (self == NULL) { 321 LOGE("Invalid input parameter."); 322 return HCF_INVALID_PARAMS; 323 } 324 if (!HcfIsClassMatch((HcfObjectBase *)self, GetSignClass())) { 325 LOGE("Class not match."); 326 return HCF_INVALID_PARAMS; 327 } 328 HcfSignImpl *tmpSelf = (HcfSignImpl *)self; 329 return tmpSelf->spiObj->engineSetSignSpecUint8Array(tmpSelf->spiObj, item, blob); 330} 331 332static HcfResult GetSignSpecInt(HcfSign *self, SignSpecItem item, int32_t *returnInt) 333{ 334 if (self == NULL || returnInt == NULL) { 335 LOGE("Invalid input parameter."); 336 return HCF_INVALID_PARAMS; 337 } 338 if (!HcfIsClassMatch((HcfObjectBase *)self, GetSignClass())) { 339 LOGE("Class not match."); 340 return HCF_INVALID_PARAMS; 341 } 342 HcfSignImpl *tmpSelf = (HcfSignImpl *)self; 343 return tmpSelf->spiObj->engineGetSignSpecInt(tmpSelf->spiObj, item, returnInt); 344} 345 346static HcfResult SignInit(HcfSign *self, HcfParamsSpec *params, HcfPriKey *privateKey) 347{ 348 if (self == NULL) { 349 LOGE("Invalid input parameter."); 350 return HCF_INVALID_PARAMS; 351 } 352 353 if (!HcfIsClassMatch((HcfObjectBase *)self, GetSignClass())) { 354 LOGE("Class not match."); 355 return HCF_INVALID_PARAMS; 356 } 357 return ((HcfSignImpl *)self)->spiObj->engineInit(((HcfSignImpl *)self)->spiObj, params, privateKey); 358} 359 360static HcfResult SignUpdate(HcfSign *self, HcfBlob *data) 361{ 362 if (self == NULL) { 363 LOGE("Invalid input parameter."); 364 return HCF_INVALID_PARAMS; 365 } 366 367 if (!HcfIsClassMatch((HcfObjectBase *)self, GetSignClass())) { 368 LOGE("Class not match."); 369 return HCF_INVALID_PARAMS; 370 } 371 return ((HcfSignImpl *)self)->spiObj->engineUpdate(((HcfSignImpl *)self)->spiObj, data); 372} 373 374static HcfResult SignDoFinal(HcfSign *self, HcfBlob *data, HcfBlob *returnSignatureData) 375{ 376 if (self == NULL) { 377 LOGE("Invalid input parameter."); 378 return HCF_INVALID_PARAMS; 379 } 380 381 if (!HcfIsClassMatch((HcfObjectBase *)self, GetSignClass())) { 382 LOGE("Class not match."); 383 return HCF_INVALID_PARAMS; 384 } 385 return ((HcfSignImpl *)self)->spiObj->engineSign(((HcfSignImpl *)self)->spiObj, data, returnSignatureData); 386} 387 388static HcfResult SetVerifySpecInt(HcfVerify *self, SignSpecItem item, int32_t saltLen) 389{ 390 if (self == NULL) { 391 LOGE("Invalid input parameter."); 392 return HCF_INVALID_PARAMS; 393 } 394 if (!HcfIsClassMatch((HcfObjectBase *)self, GetVerifyClass())) { 395 LOGE("Class not match."); 396 return HCF_INVALID_PARAMS; 397 } 398 HcfVerifyImpl *tmpSelf = (HcfVerifyImpl *)self; 399 return tmpSelf->spiObj->engineSetVerifySpecInt(tmpSelf->spiObj, item, saltLen); 400} 401 402static HcfResult GetVerifySpecString(HcfVerify *self, SignSpecItem item, char **returnString) 403{ 404 if (self == NULL || returnString == NULL) { 405 LOGE("Invalid input parameter."); 406 return HCF_INVALID_PARAMS; 407 } 408 if (!HcfIsClassMatch((HcfObjectBase *)self, GetVerifyClass())) { 409 LOGE("Class not match."); 410 return HCF_INVALID_PARAMS; 411 } 412 HcfVerifyImpl *tmpSelf = (HcfVerifyImpl *)self; 413 return tmpSelf->spiObj->engineGetVerifySpecString(tmpSelf->spiObj, item, returnString); 414} 415 416static HcfResult SetVerifySpecUint8Array(HcfVerify *self, SignSpecItem item, HcfBlob blob) 417{ 418 if (self == NULL) { 419 LOGE("Invalid input parameter."); 420 return HCF_INVALID_PARAMS; 421 } 422 if (!HcfIsClassMatch((HcfObjectBase *)self, GetVerifyClass())) { 423 LOGE("Class not match."); 424 return HCF_INVALID_PARAMS; 425 } 426 HcfVerifyImpl *tmpSelf = (HcfVerifyImpl *)self; 427 return tmpSelf->spiObj->engineSetVerifySpecUint8Array(tmpSelf->spiObj, item, blob); 428} 429 430static HcfResult GetVerifySpecInt(HcfVerify *self, SignSpecItem item, int32_t *returnInt) 431{ 432 if (self == NULL || returnInt == NULL) { 433 LOGE("Invalid input parameter."); 434 return HCF_INVALID_PARAMS; 435 } 436 if (!HcfIsClassMatch((HcfObjectBase *)self, GetVerifyClass())) { 437 LOGE("Class not match."); 438 return HCF_INVALID_PARAMS; 439 } 440 HcfVerifyImpl *tmpSelf = (HcfVerifyImpl *)self; 441 return tmpSelf->spiObj->engineGetVerifySpecInt(tmpSelf->spiObj, item, returnInt); 442} 443 444static HcfResult VerifyInit(HcfVerify *self, HcfParamsSpec *params, HcfPubKey *publicKey) 445{ 446 if (self == NULL) { 447 LOGE("Invalid input parameter."); 448 return HCF_INVALID_PARAMS; 449 } 450 451 if (!HcfIsClassMatch((HcfObjectBase *)self, GetVerifyClass())) { 452 LOGE("Class not match."); 453 return HCF_INVALID_PARAMS; 454 } 455 return ((HcfVerifyImpl *)self)->spiObj->engineInit(((HcfVerifyImpl *)self)->spiObj, params, publicKey); 456} 457 458static HcfResult VerifyUpdate(HcfVerify *self, HcfBlob *data) 459{ 460 if (self == NULL) { 461 LOGE("Invalid input parameter."); 462 return HCF_INVALID_PARAMS; 463 } 464 465 if (!HcfIsClassMatch((HcfObjectBase *)self, GetVerifyClass())) { 466 LOGE("Class not match."); 467 return HCF_INVALID_PARAMS; 468 } 469 return ((HcfVerifyImpl *)self)->spiObj->engineUpdate(((HcfVerifyImpl *)self)->spiObj, data); 470} 471 472static bool VerifyDoFinal(HcfVerify *self, HcfBlob *data, HcfBlob *signatureData) 473{ 474 if (self == NULL) { 475 LOGE("Invalid input parameter."); 476 return false; 477 } 478 if (!HcfIsClassMatch((HcfObjectBase *)self, GetVerifyClass())) { 479 LOGE("Class not match."); 480 return false; 481 } 482 return ((HcfVerifyImpl *)self)->spiObj->engineVerify(((HcfVerifyImpl *)self)->spiObj, data, signatureData); 483} 484 485static HcfResult VerifyRecover(HcfVerify *self, HcfBlob *signatureData, HcfBlob *rawSignatureData) 486{ 487 if (self == NULL) { 488 LOGE("Invalid input parameter."); 489 return HCF_INVALID_PARAMS; 490 } 491 if (!HcfIsClassMatch((HcfObjectBase *)self, GetVerifyClass())) { 492 LOGE("Class not match."); 493 return HCF_INVALID_PARAMS; 494 } 495 HcfVerifySpi *verifySpiObj = ((HcfVerifyImpl *)self)->spiObj; 496 if (verifySpiObj->engineRecover == NULL) { 497 LOGE("Not support verify recover operation."); 498 return HCF_INVALID_PARAMS; 499 } 500 501 return verifySpiObj->engineRecover(verifySpiObj, signatureData, rawSignatureData); 502} 503 504HcfResult HcfSignCreate(const char *algoName, HcfSign **returnObj) 505{ 506 LOGD("HcfSignCreate start"); 507 if ((!HcfIsStrValid(algoName, HCF_MAX_ALGO_NAME_LEN)) || (returnObj == NULL)) { 508 return HCF_INVALID_PARAMS; 509 } 510 511 HcfSignatureParams params = { 0 }; 512 if (ParseAndSetParameter(algoName, ¶ms, ParseSignatureParams) != HCF_SUCCESS) { 513 LOGE("Failed to parse params!"); 514 return HCF_INVALID_PARAMS; 515 } 516 517 HcfSignSpiCreateFunc createSpiFunc = FindSignAbility(¶ms); 518 if (createSpiFunc == NULL) { 519 LOGE("Can not find ability."); 520 return HCF_NOT_SUPPORT; 521 } 522 523 HcfSignImpl *returnSign = (HcfSignImpl *)HcfMalloc(sizeof(HcfSignImpl), 0); 524 if (returnSign == NULL) { 525 LOGE("Failed to allocate returnSign memory!"); 526 return HCF_ERR_MALLOC; 527 } 528 if (strcpy_s(returnSign->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) { 529 LOGE("Failed to copy algoName!"); 530 HcfFree(returnSign); 531 return HCF_INVALID_PARAMS; 532 } 533 HcfSignSpi *spiObj = NULL; 534 HcfResult res = createSpiFunc(¶ms, &spiObj); 535 if (res != HCF_SUCCESS) { 536 LOGE("Failed to create spi object!"); 537 HcfFree(returnSign); 538 return res; 539 } 540 returnSign->base.base.destroy = DestroySign; 541 returnSign->base.base.getClass = GetSignClass; 542 returnSign->base.getAlgoName = GetSignAlgoName; 543 returnSign->base.init = SignInit; 544 returnSign->base.update = SignUpdate; 545 returnSign->base.sign = SignDoFinal; 546 returnSign->base.setSignSpecInt = SetSignSpecInt; 547 returnSign->base.getSignSpecInt = GetSignSpecInt; 548 returnSign->base.getSignSpecString = GetSignSpecString; 549 returnSign->base.setSignSpecUint8Array = SetSignSpecUint8Array; 550 returnSign->spiObj = spiObj; 551 552 *returnObj = (HcfSign *)returnSign; 553 LOGD("HcfSignCreate end"); 554 return HCF_SUCCESS; 555} 556 557HcfResult HcfVerifyCreate(const char *algoName, HcfVerify **returnObj) 558{ 559 LOGD("HcfVerifyCreate start"); 560 if ((!HcfIsStrValid(algoName, HCF_MAX_ALGO_NAME_LEN)) || (returnObj == NULL)) { 561 return HCF_INVALID_PARAMS; 562 } 563 HcfSignatureParams params = {0}; 564 if (ParseAndSetParameter(algoName, ¶ms, ParseSignatureParams) != HCF_SUCCESS) { 565 LOGE("Failed to parse params!"); 566 return HCF_INVALID_PARAMS; 567 } 568 569 HcfVerifySpiCreateFunc createSpiFunc = FindVerifyAbility(¶ms); 570 if (createSpiFunc == NULL) { 571 return HCF_NOT_SUPPORT; 572 } 573 574 HcfVerifyImpl *returnVerify = (HcfVerifyImpl *)HcfMalloc(sizeof(HcfVerifyImpl), 0); 575 if (returnVerify == NULL) { 576 LOGE("Failed to allocate returnVerify memory!"); 577 return HCF_ERR_MALLOC; 578 } 579 if (strcpy_s(returnVerify->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) { 580 LOGE("Failed to copy algoName!"); 581 HcfFree(returnVerify); 582 return HCF_INVALID_PARAMS; 583 } 584 HcfVerifySpi *spiObj = NULL; 585 HcfResult res = createSpiFunc(¶ms, &spiObj); 586 if (res != HCF_SUCCESS) { 587 LOGE("Failed to create spi object!"); 588 HcfFree(returnVerify); 589 return res; 590 } 591 returnVerify->base.base.destroy = DestroyVerify; 592 returnVerify->base.base.getClass = GetVerifyClass; 593 returnVerify->base.getAlgoName = GetVerifyAlgoName; 594 returnVerify->base.init = VerifyInit; 595 returnVerify->base.update = VerifyUpdate; 596 returnVerify->base.verify = VerifyDoFinal; 597 returnVerify->base.recover = VerifyRecover; 598 returnVerify->base.setVerifySpecInt = SetVerifySpecInt; 599 returnVerify->base.getVerifySpecInt = GetVerifySpecInt; 600 returnVerify->base.getVerifySpecString = GetVerifySpecString; 601 returnVerify->base.setVerifySpecUint8Array = SetVerifySpecUint8Array; 602 returnVerify->spiObj = spiObj; 603 *returnObj = (HcfVerify *)returnVerify; 604 LOGD("HcfVerifyCreate end"); 605 return HCF_SUCCESS; 606} 607