1# HUKS Development 2 3## Overview 4 5### HUKS 6 7OpenHarmony Universal KeyStore (HUKS) provides lifecycle key management capabilities, including generating, storing, and destroying keys, and provides attestation for the keys stored in the HUKS. In the HUKS hierarchical architecture, the HUKS core layer (HUKS Core) at the bottom implements key management functions and runs in a secure hardware environment, such as a Trusted Execution Environment (TEE) or secure chipset. The implementation of the HUKS core layer varies depending on the secure hardware environment of the vendor. To ensure consistency of the architecture and interfaces between the service layer and application layer, the HUKS core layer defines a set of Hardware Device Interface (HDI) APIs. 8 9This document describes how to develop the HUKS core layer functions using the HUKS HDI APIs. 10 11The HUKS core layer is supposed to support the following functions: 12 13- Generation of keys. 14 15- Import of keys. 16 17- Key operations, including encryption and decryption, signing and signature verification, key derivation, key agreement, and generation of message authentication codes (MACs). 18 19- Key access control. 20 21- Key attestation. 22 23- Export of the public key from a chipset. 24 25### Basic Concepts 26 27- HUKS Core 28 29 HUKS Core is a core component that implements functions, including cryptographic calculation of keys, encryption and decryption, and key access control. Generally, it runs in a secure environment (such as a TEE or secure chipset) of a device to ensure that the keys in plaintext are never exposed outside the HUKS Core. 30 31- Key session 32 33 A key session holds the key information, including the key operation data, key properties, and access control attributes, when a key is used. You need to pass in a key alias to create a session for the key. The HUKS generates a globally unique handle for each session. A general key operation involves creating a session, passing in data and parameters, and finishing the session (or aborting the session). 34 35 36- TEE 37 38 A TEE is a secure area created by isolating software and hardware resources to protect the applications and data in the secure area from unauthorized access. This isolation mechanism yields two execution environments: TEE and Rich Execution Environment (REE). Each execution environment has independent internal data path and memory, protecting the data inside the TEE from being disclosed. The applications in an REE cannot access resources in a TEE. The applications in a TEE cannot access resources in another TEE without authorization. 39 40 41## Working Principles 42 43The HUKS is divided into the following layers: 44- Application layer: provides APIs for applications. 45- Service layer: processes key management requests from applications and performs key ciphertext management, identity verification, and key session management. 46- Core layer: implements core functions, such as key generation, key operations, key access control, and key attestation. 47 48**Figure 1** HUKS architecture 49 50 51 52## Constraints 53 54 - Keys in a secure environment in lifecycle 55 56 In the lifecycle of a key, the plaintext will never be exposed outside the HUKS Core. For the devices with a TEE or secure chipset, the HUKS Core runs in the TEE or secure chipset. This prevents the key plaintext from being disclosed even if the REE is cracked. That is why the key materials used in all HUKS passthrough HDI APIs are in ciphertext. 57 58- Encrypted keys for storage 59 60 The service keys are encrypted based on the device root key. If supported by the device, certain keys can be further protected by a password. 61 62- Strict access control over keys 63 64 Only authorized services can access keys. For security-critical services, user identity authentication can be enabled for key access. 65- Key attestation 66 67 The HUKS provides attestation for hardware-backed key storage. It proves that the key has not been tampered with, is stored in the hardware-backed HUKS Core, and has correct key properties. 68 69- Key material format 70 71 When a key (key pair, public key, or private key) is imported or exported, the key material format must meet HUKS requirements. For details, see [Key Material Formats](../../application-dev/security/huks-appendix.md#key-material-formats). 72 73- Certificate chain format 74 75 The certificate chain returned by **AttestKey()** must be assembled in the sequence of the application certificate, device certificate, CA certificate, and root certificate, with the certificate length added before each certificate. The certificate chain and its length are in the binary large object (BLOB) format. If you want to define the certificate format, the format must be the same as that parsed by the server. 76 77  78 79- KeyBlob 80The key returned by the APIs must be assembled into a **KeyBlob** based on the key storage status. For details about the APIs that must comply with this constraint, see [Available APIs](#available-apis). 81 82  83 84## How to Develop 85 86### When to Use 87 88The HUKS Core provides KeyStore capabilities for applications, including key management and cryptographic operations. If you want to replace the HUKS Core with your own implementation, you need to implement the following APIs. 89 90### Available APIs 91 92**Table 1** Available APIs 93 94| API | Description | Constraints | JS API | 95| ------------------------------------------------------------ | ---------------------------------------- | ----------------------------- | ------------------------------------------------------------ | 96| [ModuleInit()](#moduleinit) | Initializes the HUKS Core. | N/A | N/A| 97| [ModuleDestroy()](#moduledestroy) | Destroys the HUKS Core. | N/A | N/A| 98| [GenerateKey()](#generatekey) | Generates a key based on the cryptographic algorithm parameters. | The key output must be in the **KeyBlob** format. |generateKey(keyAlias: string, options: HuksOptions)| 99| [ImportKey()](#importkey) | Imports a key in plaintext. | The key output must be in the **KeyBlob** format. | importKey(keyAlias: string, options: HuksOptions)| 100| [ImportWrappedKey()](#importwrappedkey) |Imports a wrapped (encrypted) key. | The key output must be in the **KeyBlob** format. | importWrappedKey(keyAlias: string, wrappingKeyAlias: string, options: HuksOptions)| 101| [ExportPublicKey()](#exportpublickey) | Exports the public key of a key pair. |N/A | exportKey(keyAlias: string, options: HuksOptions) | 102| [Init()](#init) | Initializes a key session. This API returns a key session handle and an authentication token (optional). |N/A | init(keyAlias: string, options: HuksOptions) | 103| [Update()](#update) | Updates key operation data. |The input parameters for signature verification must be the raw data. | update(handle: number, token?: Uint8Array, options: HuksOptions) | 104| [Finish()](#finish) | Finishes a key session. |The input parameter for signature verification must be the signed data. | finish(handle: number, options: HuksOptions) | 105| [Abort()](#abort) | Aborts a key session. |N/A | abort(handle: number, options: HuksOptions) | 106| [CheckKeyValidity()](#checkkeyvalidity) | Checks the key material (ciphertext) validity. |N/A | N/A| 107| [AttestKey()](#attestkey) | Attests a key. |The output parameter must be in the certificate chain format. | attestKey(keyAlias: string, options: HuksOptions)| 108| [ExportChipsetPlatformPublicKey()](#exportchipsetplatformpublickey) | Exports the public key of a chipset key pair. | The output parameters are the raw data of ECC P-256 x-axis and y-axis values, each of which are of 32 bytes. | N/A| 109| [UpgradeKey()](#upgradekey) | Updates the key file. | N/A | N/A| 110| [GenerateRandom()](#generaterandom) | Generates a random number. | N/A | N/A| 111| [Encrypt()](#encrypt) | Encrypts data. | N/A | N/A| 112| [Decrypt()](#decrypt) | Decrypts data. | N/A | N/A| 113| [Sign()](#sign) | Signs data. | N/A | N/A| 114| [Verify()](#verify) | Verifies a signature. | N/A | N/A| 115| [AgreeKey()](#agreekey) | Performs key agreement. | N/A | N/A| 116| [DeriveKey()](#derivekey) | Derives a key. | N/A | N/A| 117| [Mac()](#mac) | Generates a MAC. | N/A | N/A| 118 119- - - 120 121#### ModuleInit 122 123**API Description** 124 125Initializes the HUKS Core. You can use this API to initialize global variables, such as the global thread locks, algorithm library, and the AuthToken key and root key used for access control. 126 127**Prototype** 128<pre><code>int32_t ModuleInit(struct IHuks *self);</code></pre> 129<details> 130 <summary><strong>Parameters</strong></summary> 131 <pre> 132 <strong>struct IHuks *self</strong> 133 Pointer to the HUKS HDI struct. 134 </pre> 135</details> 136 137<details> 138 <summary><strong>Return Value</strong></summary> 139 140 - **HKS_SUCCESS** (the value is **0**): The operation is successful. 141 142 - Other values (negative number): The operation fails. For details, see <a href="https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type.h">HksErrorCode</a>. 143</details> 144 145- - - 146 147 148#### ModuleDestroy 149 150**API Description** 151 152Destroys the HUKS Core. You can use this API to release global variables including the locks and destroy the AuthToken key and root key in the memory. 153 154**Prototype** 155<pre><code>int32_t ModuleDestroy(struct IHuks *self);</code></pre> 156<details> 157 <summary><strong>Parameters</strong></summary> 158 <pre> 159 <strong>struct IHuks *self</strong> 160 Pointer to the HUKS HDI struct. 161 </pre> 162</details> 163 164<details> 165 <summary><strong>Return Value</strong></summary> 166 167 - **HKS_SUCCESS**: The operation is successful. 168 169 - Other values: The operation fails. 170</details> 171 172- - - 173 174#### GenerateKey 175 176**API Description** 177 178Generate a key based on the **paramSet**. 179 180**Prototype** 181<pre><code>int32_t GenerateKey(struct IHuks *self, const struct HuksBlob *keyAlias, const struct HuksParamSet *paramSet, 182 const struct HuksBlob *keyIn, struct HuksBlob *encKeyOut);</code></pre> 183 184<details> 185 <summary><strong>Parameters</strong></summary> 186 <pre> 187 <strong>struct IHuks *self</strong> 188 Pointer to the HUKS HDI struct. 189 <br></br> 190 <strong>const struct HuksBlob *keyAlias</strong> 191 Pointer to the alias of the key to generate. The value must meet the following requirements: 192 1. keyAlias != null 193 2. keyAlias -> data != null 194 3. keyAlias -> dataLen != 0 195 <br></br> 196 <strong>const struct HuksParamSet *paramSet</strong> 197 Pointer to the parameters for generating the key. 198 <br></br> 199 <strong>const struct HuksBlob *keyIn</strong> 200 Pointer to the original key material to be passed in if the key is generated through key agreement or key derivation. This parameter is optional. 201 <br></br> 202 <strong>struct HuksBlob *encKeyOut</strong> 203 Pointer to the key generated in ciphertext. It holds the **paramSet** and the key ciphertext in the KeyBlob format. 204 </pre> 205</details> 206<br></br> 207 208<details> 209 <summary><strong>Constraints</strong></summary> 210 211 1. Check parameters in the API. For example, check for null pointers and whether the key algorithm is supported. 212 213 2. **keyOut** must be in the **KeyBlob** format. 214 215</details> 216<br></br> 217 218<details> 219 <summary><strong>Return Value</strong></summary> 220 221 - **HKS_SUCCESS**: The operation is successful. 222 223 - Other values: The operation fails. 224</details> 225 226- - - 227 228#### ImportKey 229 230**API Description** 231 232Imports a key in plaintext. 233 234**Prototype** 235<pre><code>int32_t ImportKey(struct IHuks *self, const struct HuksBlob *keyAlias, const struct HuksBlob *key, 236 const struct HuksParamSet *paramSet, struct HuksBlob *encKeyOut);</code></pre> 237 238<details> 239 <summary><strong>Parameters</strong></summary> 240 <pre> 241 <strong>struct IHuks *self</strong> 242 Pointer to the HUKS HDI struct. 243 <br></br> 244 <strong>const struct HuksBlob *keyAlias</strong> 245 Pointer to the alias of the key to import. The alias must meet the following requirements: 246 1. keyAlias != null 247 2. keyAlias -> data != null 248 3. keyAlias -> dataLen != 0 249 <br></br> 250 <strong>const struct HuksBlob *key</strong> 251 Pointer to the plaintext key material to import. For details about the key material format, see <a href="../application-dev/security/huks-appendix.md#key-material-formats">Key Material Formats</a>. The value must meet the following requirements: 252 1. key != null 253 2. key -> data != null 254 3. key -> dataLen != 0 255 <br></br> 256 <strong>const struct HuksParamSet *paramSet</strong> 257 Pointer to the parameters of the key to import. 258 <br></br> 259 <strong>struct HuksBlob *encKeyOut</strong> 260 Pointer to the imported key in ciphertext. It holds the **paramSet** and the imported key ciphertext in the KeyBlob format. 261 </pre> 262</details> 263<br></br> 264 265<details> 266 <summary><strong>Constraints</strong></summary> 267 268 1. Check parameters in the API. For example, check for null pointers and whether the key algorithm is supported. 269 270 2. Check that **encKeyOut** is in the KeyBlob format. 271 272</details> 273<br></br> 274 275<details> 276 <summary><strong>Return Value</strong></summary> 277 278 - **HKS_SUCCESS**: The operation is successful. 279 280 - Other values: The operation fails. 281</details> 282 283- - - 284 285#### ImportWrappedKey 286 287**API Description** 288 289Imports a wrapped key. 290 291**Prototype** 292<pre><code>int32_t ImportWrappedKey(struct IHuks *self, const struct HuksBlob *wrappingKeyAlias, 293 const struct HuksBlob *wrappingEncKey, const struct HuksBlob *wrappedKeyData, const struct HuksParamSet *paramSet, 294 struct HuksBlob *encKeyOut);</code></pre> 295 296<details> 297 <summary><strong>Parameters</strong></summary> 298 <pre> 299 <strong>struct IHuks *self</strong> 300 Pointer to the HUKS HDI struct. 301 <br></br> 302 <strong>const struct HuksBlob *wrappingKeyAlias</strong> 303 Pointer to the alias of the key used to encrypt the key to import (it is not the alias of the key to import). The value must meet the following requirements: 304 1. wrappingKeyAlias != null 305 2. wrappingKeyAlias -> data != null 306 3. wrappingKeyAlias -> dataLen != 0 307 <br></br> 308 <strong>const struct HuksBlob *wrappingEncKey</strong> 309 Pointer to the key used to encrypt the key to import. The value must meet the following requirements: 310 1. wrappingEncKey != null 311 2. wrappingEncKey -> data != null 312 3. wrappingEncKey -> dataLen != 0 313 <br></br> 314 <strong>const struct HuksBlob *wrappedKeyData</strong> 315 Pointer to the key material of the key to import. For details abut the key material format, see <a href="../../application-dev/security/huks-guidelines.md#importing-a-key-securely">Importing a Key Securely</a>. The value must meet the following requirements: 316 1. wrappedKeyData != null 317 2. wrappedKeyData -> data != null 318 3. wrappedKeyData -> dataLen != 0 319 <br></br> 320 <strong>const struct HuksParamSet *paramSet</strong> 321 Pointer to the properties of the key to import. 322 <br></br> 323 <strong>struct HuksBlob *encKeyOut</strong> 324 Pointer to the imported key material (ciphertext) in the KeyBlob format. 325 </pre> 326</details> 327<br></br> 328 329<details> 330 <summary><strong>Constraints</strong></summary> 331 332 1. Check parameters in the API. For example, check for null pointers and whether the key algorithm is supported. 333 334 2. Check that **encKeyOut** is in the KeyBlob format. 335 336</details> 337<br></br> 338 339<details> 340 <summary><strong>Return Value</strong></summary> 341 342 - **HKS_SUCCESS**: The operation is successful. 343 344 - Other values: The operation fails. 345</details> 346 347- - - 348 349#### ExportPublicKey 350 351**API Description** 352 353Exports the public key of a key pair. 354 355**Prototype** 356<pre><code>int32_t ExportPublicKey(struct IHuks *self, const struct HuksBlob *encKey, 357 const struct HuksParamSet *paramSet, struct HuksBlob *keyOut);</code></pre> 358 359<details> 360 <summary><strong>Parameters</strong></summary> 361 <pre> 362 <strong>struct IHuks *self</strong> 363 Pointer to the HUKS HDI struct. 364 <br></br> 365 <strong>const struct HuksBlob *encKey</strong> 366 Pointer to the key pair material. The value must meet the following requirements: 367 1. encKey != null 368 2. encKey -> data != null 369 3. encKey -> dataLen != 0 370 <br></br> 371 <strong>const struct HuksParamSet *paramSet</strong> 372 Pointer to the parameters for exporting the public key. By default, this parameter is left blank. 373 <br></br> 374 <strong>struct HuksBlob *keyOut</strong> 375 Pointer to the public key exported. 376 </pre> 377</details> 378<br></br> 379 380<details> 381 <summary><strong>Return Value</strong></summary> 382 383 - **HKS_SUCCESS**: The operation is successful. 384 385 - Other values: The operation fails. 386</details> 387 388- - - 389 390#### Init 391 392**API Description** 393 394Initializes a key session. You need to pass in the key material in ciphertext. The HUKS Core decrypts the ciphertext and generates a key session handle and an authentication token (if required). 395 396**Prototype** 397<pre><code>int32_t Init(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet, 398 struct HuksBlob *handle, struct HuksBlob *token);</code></pre> 399 400<details> 401 <summary><strong>Parameters</strong></summary> 402 <pre> 403 <strong>struct IHuks *self</strong> 404 Pointer to the HUKS HDI struct. 405 <br></br> 406 <strong>const struct HuksBlob *encKey</strong> 407 Pointer to the ciphertext material of the key to be operated. The value must meet the following requirements: 408 1. encKey != null 409 2. encKey -> data != null 410 3. encKey -> dataLen != 0 411 <br></br> 412 <strong>const struct HuksParamSet *paramSet</strong> 413 Pointer to the parameters for initializing the key session. 414 <br></br> 415 <strong>struct HuksBlob *handle</strong> 416 Pointer to the key session handle generated, which identifies the key session in Update(), Finish(), and Abort(). 417 <br></br> 418 <strong>struct HuksBlob *token</strong> 419 Pointer to the authentication token generated for key access control (if required). 420 </pre> 421</details> 422<br></br> 423 424<details> 425 <summary><strong>Constraints</strong></summary> 426 427This API must be used with **Update()**, **Finish()**, and **Abort()** together. 428 429</details> 430<br></br> 431 432<details> 433 <summary><strong>Return Value</strong></summary> 434 435 - **HKS_SUCCESS**: The operation is successful. 436 437 - Other values: The operation fails. 438</details> 439 440- - - 441 442#### Update 443 444**API Description** 445 446Updates data for the key operation by segment according to the cryptographic algorithm requirements. 447 448**Prototype** 449<pre><code>int32_t Update(struct IHuks *self, const struct HuksBlob *handle, const struct HuksParamSet *paramSet, 450 const struct HuksBlob *inData, struct HuksBlob *outData);</code></pre> 451 452<details> 453 <summary><strong>Parameters</strong></summary> 454 <pre> 455 <strong>struct IHuks *self</strong> 456 Pointer to the HUKS HDI struct. 457 <br></br> 458 <strong>const struct HuksBlob *handle</strong> 459 Pointer to the handle of the key session. 460 <br></br> 461 <strong> const struct HuksParamSet *paramSet</strong> 462 Pointer to the parameters for the update operation. 463 <br></br> 464 <strong> const struct HuksBlob *inData</strong> 465 Pointer to the data to be passed in. 466 <br></br> 467 <strong> struct HuksBlob *outData</strong> 468 Pointer to the result of the update operation. 469 </pre> 470</details> 471<br></br> 472 473<details> 474 <summary><strong>Constraints</strong></summary> 475 476 1. This API must be used with **Init()**, **Finish()**, and **Abort()** together. 477 478 2. **inData** must pass in the raw data when signature verification is performed. 479 480</details> 481<br></br> 482 483<details> 484 <summary><strong>Return Value</strong></summary> 485 486 - **HKS_SUCCESS**: The operation is successful. 487 488 - Other values: The operation fails. 489</details> 490 491- - - 492 493#### Finish 494 495**API Description** 496 497Finishes the key session. 498 499**Prototype** 500<pre><code>int32_t Finish(struct IHuks *self, const struct HuksBlob *handle, const struct HuksParamSet *paramSet, 501 const struct HuksBlob *inData, struct HuksBlob *outData);</code></pre> 502 503<details> 504 <summary><strong>Parameters</strong></summary> 505 <pre> 506 <strong>struct IHuks *self</strong> 507 Pointer to the HUKS HDI struct. 508 <br></br> 509 <strong>const struct HuksBlob *handle</strong> 510 Pointer to the handle of the key session. 511 <br></br> 512 <strong>const struct HuksParamSet *paramSet</strong> 513 Pointer to the parameters for the last operation. 514 <br></br> 515 <strong>const struct HuksBlob *inData</strong> 516 Pointer to the last data to be passed in. 517 <br></br> 518 <strong>struct HuksBlob *outData</strong> 519 Pointer to the result of the key operation. 520 </pre> 521</details> 522<br></br> 523 524<details> 525 <summary><strong>Constraints</strong></summary> 526 527 1. This API must be used with **Init()**, **Update()**, and **Abort()** together. 528 529 2. In signature verification, **inData** must pass in the signature data to be verified. The return value indicates whether the signature has passed the verification. 530 531</details> 532<br></br> 533 534<details> 535 <summary><strong>Return Value</strong></summary> 536 537 - **HKS_SUCCESS**: The operation is successful. 538 539 - Other values: The operation fails. 540</details> 541 542- - - 543 544#### Abort 545 546**API Description** 547 548Aborts the key session. When an error occurs in any of the **Init**, **Update**, and **Finish** operations, call this API to terminate the key session. 549 550**Prototype** 551<pre><code>int32_t Abort(struct IHuks *self, const struct HuksBlob *handle, const struct HuksParamSet *paramSet);</code></pre> 552<details> 553 <summary><strong>Parameters</strong></summary> 554 <pre> 555 <strong>struct IHuks *self</strong> 556 Pointer to the HUKS HDI struct. 557 <br></br> 558 <strong>const struct HuksBlob *handle</strong> 559 Pointer to the handle of the key session. 560 <br></br> 561 <strong>const struct HuksParamSet *paramSet</strong> 562 Pointer to the parameters of the **Abort** operation. 563 </pre> 564</details> 565<br></br> 566 567<details> 568 <summary><strong>Constraints</strong></summary> 569 570This API must be used with **Init()**, **Update()**, and **Finish()** together. 571 572</details> 573<br></br> 574 575<details> 576 <summary><strong>Return Value</strong></summary> 577 578 - **HKS_SUCCESS**: The operation is successful. 579 580 - Other values: The operation fails. 581</details> 582 583- - - 584 585#### CheckKeyValidity 586 587**API Description** 588 589Checks key validity. 590 591**Prototype** 592<pre><code>int32_t CheckKeyValidity(struct IHuks *self, const struct HuksParamSet *paramSet, 593 const struct HuksBlob *encKey);</code></pre> 594 595<details> 596 <summary><strong>Parameters</strong></summary> 597 <pre> 598 <strong>struct IHuks *self</strong> 599 Pointer to the HUKS HDI struct. 600 <br></br> 601 <strong>const struct HuksParamSet *paramSet</strong> 602 Pointer to the parameters for checking the key integrity. By default, this parameter is left empty. 603 <br></br> 604 <strong>const struct HuksBlob *encKey</strong> 605 Pointer to the key material (ciphertext) to be checked. 606 </pre> 607</details> 608<br></br> 609 610<details> 611 <summary><strong>Return Value</strong></summary> 612 613 - **HKS_SUCCESS**: The operation is successful. 614 615 - Other values: The operation fails. 616</details> 617 618- - - 619 620#### AttestKey 621 622**API Description** 623 624Attests a key. 625 626**Prototype** 627<pre><code>int32_t AttestKey(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet, 628 struct HuksBlob *certChain);</code></pre> 629 630<details> 631 <summary><strong>Parameters</strong></summary> 632 <pre> 633 <strong>struct IHuks *self</strong> 634 Pointer to the HUKS HDI struct. 635 <br></br> 636 <strong>const struct HuksBlob *encKey</strong> 637 Pointer to the key pair material in ciphertext. 638 <br></br> 639 <strong>const struct HuksParamSet *paramSet</strong> 640 Pointer to the parameters (such as the challenge) for obtaining the key certificate chain. 641 <br></br> 642 <strong>struct HuksBlob *certChain</strong> 643 Pointer to the certificate chain obtained. 644 </pre> 645</details> 646<br></br> 647 648<details> 649 <summary><strong>Constraints</strong></summary> 650 651**certChain** must comply with the certificate chain described in [Constraints](#constraints). 652 653</details> 654<br></br> 655 656<details> 657 <summary><strong>Return Value</strong></summary> 658 659 - **HKS_SUCCESS**: The operation is successful. 660 661 - Other values: The operation fails. 662</details> 663 664- - - 665 666#### ExportChipsetPlatformPublicKey 667 668**API Description** 669 670Exports the public key of a chipset key pair. 671 672**Prototype** 673<pre><code>int32_t ExportChipsetPlatformPublicKey(struct IHuks *self, const struct HuksBlob *salt, 674 enum HuksChipsetPlatformDecryptScene scene, struct HuksBlob *publicKey);</code></pre> 675 676<details> 677 <summary><strong>Parameters</strong></summary> 678 <pre> 679 <strong>struct IHuks *self</strong> 680 Pointer to the HUKS HDI struct. 681 <br></br> 682 <strong>const struct HuksBlob *salt</strong> 683 Pointer to the factor used to derive the chipset key pair. 684 <br></br> 685 <strong>enum HuksChipsetPlatformDecryptScene scene</strong> 686 Expected chipset decryption scenario. 687 <br></br> 688 <strong>struct HuksBlob *publicKey</strong> 689 Pointer to the raw data of ECC P-256 x-axis and y-axis values, each of which are of 32 bytes. 690 </pre> 691</details> 692<br></br> 693 694<details> 695 <summary><strong>Constraints</strong></summary> 696 697The input parameter **salt** must be of 16 bytes, and the content of the last byte will be ignored and filled by HUKS based on **scene**. 698Currently, the chipset key pairs of HUKS are implemented by software. An ECC P-256 key pair is hard-coded, and the **salt** value is ignored. That is, the derived keys are the same regardless of the **salt**. In the hardware-based implementation of chipset key pairs, **salt** is a factor used to derive the key. That is, the key pair derived varies with the **salt** value. 699 700</details> 701<br></br> 702 703<details> 704 <summary><strong>Return Value</strong></summary> 705 706 - **HKS_SUCCESS**: The operation is successful. 707 708 - Other values: The operation fails. 709</details> 710 711- - - 712 713#### UpgradeKey 714 715**API Description** 716 717Updates the key file when the key file version is earlier than the latest version. 718 719**Prototype** 720<pre><code>int32_t UpgradeKey(struct IHuks *self, const struct HuksBlob *encOldKey, const struct HuksParamSet *paramSet, 721 struct HuksBlob *encNewKey);</code></pre> 722 723<details> 724 <summary><strong>Parameters</strong></summary> 725 <pre> 726 <strong>struct IHuks *self</strong> 727 Pointer to the HUKS HDI struct. 728 <br></br> 729 <strong>const struct HuksBlob *encOldKey</strong> 730 Pointer to the key file data to update. 731 <br></br> 732 <strong>const struct HuksParamSet *paramSet</strong> 733 Pointer to the parameters for updating the key file data. 734 <br></br> 735 <strong>struct HuksBlob *newKey</strong> 736 Pointer to the new key file data. 737 </pre> 738</details> 739<br></br> 740 741<details> 742 <summary><strong>Return Value</strong></summary> 743 744 - **HKS_SUCCESS**: The operation is successful. 745 746 - Other values: The operation fails. 747</details> 748 749- - - 750 751#### GenerateRandom 752 753**API Description** 754 755Generates a random number. 756 757**Prototype** 758<pre><code>int32_t GenerateRandom(struct IHuks *self, const struct HuksParamSet *paramSet, struct HuksBlob *random);</code></pre> 759<details> 760 <summary><strong>Parameters</strong></summary> 761 <pre> 762 <strong>struct IHuks *self</strong> 763 Pointer to the HUKS HDI struct. 764 <br></br> 765 <strong>const struct HuksParamSet *paramSet</strong> 766 Pointer to the parameters of the random number to generate, such as the length. 767 <br></br> 768 <strong>struct HuksBlob *random</strong> 769 Pointer to the random number generated. 770 </pre> 771</details> 772<br></br> 773 774<details> 775 <summary><strong>Return Value</strong></summary> 776 777 - **HKS_SUCCESS**: The operation is successful. 778 779 - Other values: The operation fails. 780</details> 781 782- - - 783 784#### Sign 785 786**API Description** 787 788Signs data. 789 790**Prototype** 791<pre><code>int32_t Sign(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet, 792 const struct HuksBlob *srcData, struct HuksBlob *signature);</code></pre> 793 794<details> 795 <summary><strong>Parameters</strong></summary> 796 <pre> 797 <strong>struct IHuks *self</strong> 798 Pointer to the HUKS HDI struct. 799 <br></br> 800 <strong>const struct HuksBlob *encKey</strong> 801 Pointer to the key pair material (ciphertext) used for signing. 802 <br></br> 803 <strong>const struct HuksParamSet *paramSet</strong> 804 Pointer to the parameters used for signing, such as the digest mode. 805 <br></br> 806 <strong>const struct HuksBlob *srcData</strong> 807 Pointer to the data to be signed. 808 <br></br> 809 <strong>struct HuksBlob *signature</strong> 810 Pointer to the signature generated. 811 </pre> 812</details> 813<br></br> 814 815<details> 816 <summary><strong>Return Value</strong></summary> 817 818 - **HKS_SUCCESS**: The operation is successful. 819 820 - Other values: The operation fails. 821</details> 822 823- - - 824 825#### Verify 826 827**API Description** 828 829Verifies a digital signature. 830 831**Prototype** 832<pre><code>int32_t Verify(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet, 833 const struct HuksBlob *srcData, const struct HuksBlob *signature);</code></pre> 834 835<details> 836 <summary><strong>Parameters</strong></summary> 837 <pre> 838 <strong>struct IHuks *self</strong> 839 Pointer to the HUKS HDI struct. 840 <br></br> 841 <strong>const struct HuksBlob *encKey</strong> 842 Pointer to the key pair material (ciphertext) used for signature verification. 843 <br></br> 844 <strong>const struct HuksParamSet *paramSet</strong> 845 Pointer to the parameters for signature verification, such as the digest mode. 846 <br></br> 847 <strong>const struct HuksBlob *srcData</strong> 848 Pointer to the data with the signature to be verified. 849 <br></br> 850 <strong>const struct HuksBlob *signature</strong> 851 Pointer to the signature to verify. 852 </pre> 853</details> 854<br></br> 855 856<details> 857 <summary><strong>Return Value</strong></summary> 858 859 - **HKS_SUCCESS**: The operation is successful. 860 861 - Other values: The operation fails. 862</details> 863 864- - - 865 866#### Encrypt 867 868**API Description** 869 870Encrypts data. Different from the key session APIs that must be used together, this API completes data encryption in a single call. 871 872**Prototype** 873<pre><code>int32_t Encrypt(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet, 874 const struct HuksBlob *plainText, struct HuksBlob *cipherText);</code></pre> 875 876<details> 877 <summary><strong>Parameters</strong></summary> 878 <pre> 879 <strong>struct IHuks *self</strong> 880 Pointer to the HUKS HDI struct. 881 <br></br> 882 <strong>const struct HuksBlob *encKey</strong> 883 Pointer to the key material (ciphertext) used for encryption. 884 <br></br> 885 <strong>const struct HuksParamSet *paramSet</strong> 886 Pointer to the key parameters for encryption, such as the key working mode and padding mode. 887 <br></br> 888 <strong>const struct HuksBlob *plainText</strong> 889 Pointer to the plaintext data to encrypt. 890 <br></br> 891 <strong>const struct HuksBlob *cipherText</strong> 892 Pointer to the encrypted data (data in ciphertext). 893 </pre> 894</details> 895<br></br> 896 897<details> 898 <summary><strong>Return Value</strong></summary> 899 900 - **HKS_SUCCESS**: The operation is successful. 901 902 - Other values: The operation fails. 903</details> 904 905- - - 906 907#### Decrypt 908 909**API Description** 910 911Decrypts data. Different from the key session APIs that must be used together, this API completes data decryption in a single call. 912 913**Prototype** 914<pre><code>int32_t Decrypt(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet, 915 const struct HuksBlob *cipherText, struct HuksBlob *plainText);</code></pre> 916 917<details> 918 <summary><strong>Parameters</strong></summary> 919 <pre> 920 <strong>struct IHuks *self</strong> 921 Pointer to the HUKS HDI struct. 922 <br></br> 923 <strong>const struct HuksBlob *encKey</strong> 924 Pointer to the key material (ciphertext) used for decryption. 925 <br></br> 926 <strong>const struct HuksParamSet *paramSet</strong> 927 Pointer to the key parameters for decryption, such as the key working mode and padding mode. 928 <br></br> 929 <strong>const struct HuksBlob *cipherText</strong> 930 Pointer to the data to decrypt. 931 <br></br> 932 <strong>const struct HuksBlob *plainText</strong> 933 Pointer to the encrypted data in plaintext. 934 </pre> 935</details> 936<br></br> 937 938<details> 939 <summary><strong>Return Value</strong></summary> 940 941 - **HKS_SUCCESS**: The operation is successful. 942 943 - Other values: The operation fails. 944</details> 945 946- - - 947 948#### AgreeKey 949 950**API Description** 951 952Performs key agreement. Different from the key session APIs that must be used together, this API returns an agreed key in a single call. 953 954**Prototype** 955<pre><code>int32_t AgreeKey(struct IHuks *self, const struct HuksParamSet *paramSet, 956 const struct HuksBlob *encPrivateKey, const struct HuksBlob *peerPublicKey, struct HuksBlob *agreedKey);</code></pre> 957 958<details> 959 <summary><strong>Parameters</strong></summary> 960 <pre> 961 <strong>struct IHuks *self</strong> 962 Pointer to the HUKS HDI struct. 963 <br></br> 964 <strong>const struct HuksParamSet *paramSet</strong> 965 Pointer to the parameters for key agreement, such as the length of the agreed key. 966 <br></br> 967 <strong>const struct HuksBlob *encPrivateKey</strong> 968 Pointer to the private key material (ciphertext) used for key agreement. 969 <br></br> 970 <strong>const struct HuksBlob *peerPublicKey</strong> 971 Pointer to the public key (plaintext) used for key agreement. 972 <br></br> 973 <strong>struct HuksBlob *agreedKey</strong> 974 Pointer to the agreed key in plaintext. 975 </pre> 976</details> 977<br></br> 978 979<details> 980 <summary><strong>Return Value</strong></summary> 981 982 - **HKS_SUCCESS**: The operation is successful. 983 984 - Other values: The operation fails. 985</details> 986 987- - - 988 989#### DeriveKey 990 991**API Description** 992 993Derives a key. Different from the key session APIs that must be used together, this API derives a key in a single call. 994 995**Prototype** 996<pre><code>int32_t DeriveKey(struct IHuks *self, const struct HuksParamSet *paramSet, const struct HuksBlob *encKdfKey, 997 struct HuksBlob *derivedKey);</code></pre> 998 999<details> 1000 <summary><strong>Parameters</strong></summary> 1001 <pre> 1002 <strong>struct IHuks *self</strong> 1003 Pointer to the HUKS HDI struct. 1004 <br></br> 1005 <strong>const struct HuksParamSet *paramSet</strong> 1006 Pointer to the parameters for key derivation, such as the length of the derived key. 1007 <br></br> 1008 <strong>const struct HuksBlob *encKdfKey</strong> 1009 Pointer to the key material (ciphertext) used for deriving a key. 1010 <br></br> 1011 <strong>struct HuksBlob *derivedKey</strong> 1012 Pointer to the derived key in plaintext. 1013 </pre> 1014</details> 1015<br></br> 1016 1017<details> 1018 <summary><strong>Return Value</strong></summary> 1019 1020 - **HKS_SUCCESS**: The operation is successful. 1021 1022 - Other values: The operation fails. 1023</details> 1024 1025- - - 1026 1027#### Mac 1028 1029**API Description** 1030 1031Generates a MAC based on the given key. 1032 1033**Prototype** 1034<pre><code>int32_t Mac(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet, 1035 const struct HuksBlob *srcData, struct HuksBlob *mac);</code></pre> 1036 1037<details> 1038 <summary><strong>Parameters</strong></summary> 1039 <pre> 1040 <strong>struct IHuks *self</strong> 1041 Pointer to the HUKS HDI struct. 1042 <br></br> 1043 <strong>const struct HuksBlob *encKey</strong> 1044 Pointer to the key material (ciphertext) used to generate the MAC. 1045 <br></br> 1046 <strong>const struct HuksParamSet *paramSet</strong> 1047 Pointer to the parameters for generating the MAC. 1048 <br></br> 1049 <strong>const struct HuksBlob *srcData</strong> 1050 Pointre to the source data for which the MAC is to be generated. 1051 <br></br> 1052 <strong>struct HuksBlob *mac</strong> 1053 Pointer to the MAC generated. 1054 </pre> 1055</details> 1056<br></br> 1057 1058<details> 1059 <summary><strong>Return Value</strong></summary> 1060 1061 - **HKS_SUCCESS**: The operation is successful. 1062 1063 - Other values: The operation fails. 1064</details> 1065 1066- - - 1067### Development Procedure 1068 1069#### Directory Structure 1070 1071The code for HDI adaptation is in the following directory. 1072 1073```undefined 1074//drivers_peripheral/huks 1075├── BUILD.gn # Build script. 1076├── hdi_service # Dependency loaded from libhuks_engine_core_standard.z.so (software implementation of the HUKS Core for reference only) by using dlopen(). 1077 ├── huks_sa_type.h # Defines the data structs used in the HUKS service layer. 1078 ├── huks_sa_hdi_struct.h # Defines the function pointer structs in libhuks_engine_core_standard.z.so. 1079 ├── huks_hdi_template.h # Defines the conversion between the data structs of the HUKS service layer and the HDI. 1080 ├── huks_hdi_service.c # Implementation of the HUKS passthrough HDI APIs. 1081 └── huks_hdi_passthrough_adapter.c # Adaptation of HUKS passthrough HDI APIs to the HUKS Core. 1082└── test # Test code for the HUKS HDI APIs. 1083 ├── BUILD.gn # Build script. 1084 ├── fuzztest # Fuzz test. 1085 └── unittest # Unit test. 1086``` 1087 1088The code of the HUKS Core software implementation is in the following directory. 1089 1090```undefined 1091//base/security/huks/services/huks_standard/huks_engine 1092├── BUILD.gn # Build script. 1093├── core_dependency # HUKS Core dependency. 1094└── core # Software implementation of the HUKS Core. 1095 ├── BUILD.gn # Build script. 1096 ├── include 1097 └── src 1098 ├── hks_core_interfaces.c # Adaptation of the HDI to the HUKS Core. 1099 └── hks_core_service.c # HUKS Core implementation. 1100 └── ... # Code of other functions. 1101``` 1102**CAUTION** 1103 1104<summary><strong>The software implementation of the HUKS Core contains hard-coded sensitive data, including the root key, AuthToken key for access control, key used to encrypt AuthToken, and certificate. You need to replace these code with your own implementation. /summary> 1105 1106 - Root key 1107 1108 The root key is used to encrypt the HUKS service key and is generally derived from the device root key. It is hard-coded in the HUKS Core software implementation. For details, see <a href="https://gitee.com/openharmony/security_huks/blob/master/frameworks/huks_standard/main/crypto_engine/openssl/src/hks_openssl_get_main_key.c">hks_openssl_get_main_key.c</a>. 1109 1110 - Key for generating an HMAC on AuthToken 1111 1112 The key is used to generate an HMAC on AuthToken by the UserIAM for access control. The value is **huks_default_user_auth_token_key** and hard-coded in the HUKS Core software implementation. For details about the code, see <a href="https://gitee.com/openharmony/security_huks/blob/master/services/huks_standard/huks_engine/main/core/src/hks_keyblob.c">hks_keyblob.c</a>. 1113 1114 - Key for encrypting sensitive fields of AuthToken 1115 1116 The key is used to encrypt sensitive fields of AuthToken in access control. The value is **huks_default_user_auth_token_key** and hard-coded in the HUKS Core software implementation. For details about the code, see <a href="https://gitee.com/openharmony/security_huks/blob/master/services/huks_standard/huks_engine/main/core/src/hks_keyblob.c">hks_keyblob.c</a>. 1117 1118 - Root certificate, device CA, and device certificate 1119 1120 The root certificate, device CA, and device certificate are used for key attestation and preset in the secure storage of the hardware device by the device certificate management module. These certificates are hard-coded in the HUKS Core software implementation. For details about the code, see <a href="https://gitee.com/openharmony/security_huks/blob/master/services/huks_standard/huks_engine/main/device_cert_manager/include/dcm_certs_and_key.h">dcm_certs_and_key.h</a>. 1121 1122#### Example 1123 1124The following uses the adaptation of the key session APIs **Init**, **Update**, and **Finish** in the HUKS Core as an example. The sample code is for reference only and cannot be used directly. For details about the executable code, see [HUKS source code](https://gitee.com/openharmony/security_huks). 1125 11261. Create a handle to identify information about key operations in a session. With this handle, multiple operations on the same key can be performed. 1127 1128 ```c 1129 1130 // Initialize the key session. 1131 1132 int32_t HksCoreInit(const struct HuksBlob *key, const struct HuksParamSet *paramSet, struct HuksBlob *handle, 1133 struct HuksBlob *token) 1134 { 1135 HKS_LOG_D("HksCoreInit in Core start"); 1136 uint32_t pur = 0; 1137 uint32_t alg = 0; 1138 // Check parameters. 1139 if (key == NULL || paramSet == NULL || handle == NULL || token == NULL) { 1140 HKS_LOG_E("the pointer param entered is invalid"); 1141 return HKS_FAILURE; 1142 } 1143 1144 if (handle->size < sizeof(uint64_t)) { 1145 HKS_LOG_E("handle size is too small, size : %u", handle->size); 1146 return HKS_ERROR_INSUFFICIENT_MEMORY; 1147 } 1148 // Decrypt the key file. 1149 struct HuksKeyNode *keyNode = HksCreateKeyNode(key, paramSet); 1150 if (keyNode == NULL || handle == NULL) { 1151 HKS_LOG_E("the pointer param entered is invalid"); 1152 return HKS_ERROR_BAD_STATE; 1153 } 1154 // Store information in a session based on the handle. The information stored can be used for the Update() and Finish() operations on the key. 1155 handle->size = sizeof(uint64_t); 1156 (void)memcpy_s(handle->data, handle->size, &(keyNode->handle), handle->size); 1157 // Obtain the algorithm from the parameters. 1158 int32_t ret = GetPurposeAndAlgorithm(paramSet, &pur, &alg); 1159 if (ret != HKS_SUCCESS) { 1160 HksDeleteKeyNode(keyNode->handle); 1161 return ret; 1162 } 1163 // Check key parameters. 1164 ret = HksCoreSecureAccessInitParams(keyNode, paramSet, token); 1165 if (ret != HKS_SUCCESS) { 1166 HKS_LOG_E("init secure access params failed"); 1167 HksDeleteKeyNode(keyNode->handle); 1168 return ret; 1169 } 1170 // Obtain the initialization handler from the algorithm library based on the key purpose. 1171 uint32_t i; 1172 uint32_t size = HKS_ARRAY_SIZE(g_hksCoreInitHandler); 1173 for (i = 0; i < size; i++) { 1174 if (g_hksCoreInitHandler[i].pur == pur) { 1175 HKS_LOG_E("Core HksCoreInit [pur] = %d, pur = %d", g_hksCoreInitHandler[i].pur, pur); 1176 ret = g_hksCoreInitHandler[i].handler(keyNode, paramSet, alg); 1177 break; 1178 } 1179 } 1180 // Check exception results. 1181 if (ret != HKS_SUCCESS) { 1182 HksDeleteKeyNode(keyNode->handle); 1183 HKS_LOG_E("CoreInit failed, ret : %d", ret); 1184 return ret; 1185 } 1186 1187 if (i == size) { 1188 HksDeleteKeyNode(keyNode->handle); 1189 HKS_LOG_E("don't found purpose, pur : %u", pur); 1190 return HKS_FAILURE; 1191 } 1192 1193 HKS_LOG_D("HksCoreInit in Core end"); 1194 return ret; 1195 } 1196 ``` 1197 11982. Obtain the context based on the handle, and pass in data by segment to obtain the operation result or append data. 1199 1200 ```c 1201 // Update data by segment. 1202 int32_t HksCoreUpdate(const struct HuksBlob *handle, const struct HuksParamSet *paramSet, const struct HuksBlob *inData, 1203 struct HuksBlob *outData) 1204 { 1205 HKS_LOG_D("HksCoreUpdate in Core start"); 1206 uint32_t pur = 0; 1207 uint32_t alg = 0; 1208 // Check parameters. 1209 if (handle == NULL || paramSet == NULL || inData == NULL) { 1210 HKS_LOG_E("the pointer param entered is invalid"); 1211 return HKS_FAILURE; 1212 } 1213 1214 uint64_t sessionId; 1215 struct HuksKeyNode *keyNode = NULL; 1216 // Obtain the context required for the key session operation based on the handle. 1217 int32_t ret = GetParamsForUpdateAndFinish(handle, &sessionId, &keyNode, &pur, &alg); 1218 if (ret != HKS_SUCCESS) { 1219 HKS_LOG_E("GetParamsForCoreUpdate failed"); 1220 return ret; 1221 } 1222 // Verify key parameters. 1223 ret = HksCoreSecureAccessVerifyParams(keyNode, paramSet); 1224 if (ret != HKS_SUCCESS) { 1225 HksDeleteKeyNode(sessionId); 1226 HKS_LOG_E("HksCoreUpdate secure access verify failed"); 1227 return ret; 1228 } 1229 // Call the key handler from the corresponding algorithm library. 1230 uint32_t i; 1231 uint32_t size = HKS_ARRAY_SIZE(g_hksCoreUpdateHandler); 1232 for (i = 0; i < size; i++) { 1233 if (g_hksCoreUpdateHandler[i].pur == pur) { 1234 struct HuksBlob appendInData = { 0, NULL }; 1235 ret = HksCoreAppendAuthInfoBeforeUpdate(keyNode, pur, paramSet, inData, &appendInData); 1236 if (ret != HKS_SUCCESS) { 1237 HKS_LOG_E("before update: append auth info failed"); 1238 break; 1239 } 1240 ret = g_hksCoreUpdateHandler[i].handler(keyNode, paramSet, 1241 appendInData.data == NULL ? inData : &appendInData, outData, alg); 1242 if (appendInData.data != NULL) { 1243 HKS_FREE_BLOB(appendInData); 1244 } 1245 break; 1246 } 1247 } 1248 // Check exception results. 1249 if (ret != HKS_SUCCESS) { 1250 HksDeleteKeyNode(keyNode->handle); 1251 HKS_LOG_E("CoreUpdate failed, ret : %d", ret); 1252 return ret; 1253 } 1254 1255 if (i == size) { 1256 HksDeleteKeyNode(sessionId); 1257 HKS_LOG_E("don't found purpose, pur : %u", pur); 1258 return HKS_FAILURE; 1259 } 1260 return ret; 1261 } 1262 ``` 1263 12643. Finish the key operation to obtain the result, and destroy the handle. 1265 1266 ```c 1267 // Finish the key session operation. 1268 int32_t HksCoreFinish(const struct HuksBlob *handle, const struct HuksParamSet *paramSet, const struct HuksBlob *inData, 1269 struct HuksBlob *outData) 1270 { 1271 HKS_LOG_D("HksCoreFinish in Core start"); 1272 uint32_t pur = 0; 1273 uint32_t alg = 0; 1274 // Check parameters. 1275 if (handle == NULL || paramSet == NULL || inData == NULL) { 1276 HKS_LOG_E("the pointer param entered is invalid"); 1277 return HKS_FAILURE; 1278 } 1279 1280 uint64_t sessionId; 1281 struct HuksKeyNode *keyNode = NULL; 1282 // Obtain the context required for the key session operation based on the handle. 1283 int32_t ret = GetParamsForUpdateAndFinish(handle, &sessionId, &keyNode, &pur, &alg); 1284 if (ret != HKS_SUCCESS) { 1285 HKS_LOG_E("GetParamsForCoreUpdate failed"); 1286 return ret; 1287 } 1288 // Verify key parameters. 1289 ret = HksCoreSecureAccessVerifyParams(keyNode, paramSet); 1290 if (ret != HKS_SUCCESS) { 1291 HksDeleteKeyNode(sessionId); 1292 HKS_LOG_E("HksCoreFinish secure access verify failed"); 1293 return ret; 1294 } 1295 // Call the key handler from the corresponding algorithm library. 1296 uint32_t i; 1297 uint32_t size = HKS_ARRAY_SIZE(g_hksCoreFinishHandler); 1298 for (i = 0; i < size; i++) { 1299 if (g_hksCoreFinishHandler[i].pur == pur) { 1300 uint32_t outDataBufferSize = (outData == NULL) ? 0 : outData->size; 1301 struct HuksBlob appendInData = { 0, NULL }; 1302 ret = HksCoreAppendAuthInfoBeforeFinish(keyNode, pur, paramSet, inData, &appendInData); 1303 if (ret != HKS_SUCCESS) { 1304 HKS_LOG_E("before finish: append auth info failed"); 1305 break; 1306 } 1307 ret = g_hksCoreFinishHandler[i].handler(keyNode, paramSet, 1308 appendInData.data == NULL ? inData : &appendInData, outData, alg); 1309 if (appendInData.data != NULL) { 1310 HKS_FREE_BLOB(appendInData); 1311 } 1312 if (ret != HKS_SUCCESS) { 1313 break; 1314 } 1315 // Append the end label of the key operation. 1316 ret = HksCoreAppendAuthInfoAfterFinish(keyNode, pur, paramSet, outDataBufferSize, outData); 1317 break; 1318 } 1319 } 1320 if (i == size) { 1321 HKS_LOG_E("don't found purpose, pur : %d", pur); 1322 ret = HKS_FAILURE; 1323 } 1324 // Delete the session. 1325 HksDeleteKeyNode(sessionId); 1326 HKS_LOG_D("HksCoreFinish in Core end"); 1327 return ret; 1328 } 1329 ``` 1330 1331### Debugging 1332 1333Use [HUKS JS APIs](https://gitee.com/openharmony/security_huks/blob/master/interfaces/kits/js/@ohos.security.huks.d.ts) to develop a JavaScript application to verify HUKS capabilities. 1334 1335The JS APIs corresponding to HDI APIs are provided in [Available APIs](#available-apis). You can use the JS APIs to verify the capabilities of the corresponding HDI APIs or perform complete key operations to verify the capabilities of the APIs. 1336 1337The following JS test code is for reference only. If the entire process goes properly, the HDI APIs are functioning. For more key operation types and samples, see [huks-guidelines.md](../../application-dev/security/huks-guidelines.md). 1338 1339**Generating an AES Key and Encrypting Data** 1340 13411. Import the HUKS module. 1342 1343 ```ts 1344 import huks from '@ohos.security.huks' 1345 ``` 1346 13472. Use **generateKey()** to generate a key. 1348 1349 ```ts 1350 import { BusinessError } from '@ohos.base'; 1351 let aesKeyAlias = 'test_aesKeyAlias'; 1352 let handle = 0; 1353 let IV = '001122334455'; 1354 1355 class HuksProperties { 1356 tag: huks.HuksTag = huks.HuksTag.HUKS_TAG_ALGORITHM; 1357 value: huks.HuksKeyAlg | huks.HuksKeySize | huks.HuksKeyPurpose = huks.HuksKeyAlg.HUKS_ALG_ECC; 1358 } 1359 1360 class HuksProperties1 { 1361 tag: huks.HuksTag = huks.HuksTag.HUKS_TAG_ALGORITHM; 1362 value: huks.HuksKeyAlg | huks.HuksKeySize | huks.HuksKeyPurpose | huks.HuksKeyPadding | huks.HuksCipherMode | Uint8Array = huks.HuksKeyAlg.HUKS_ALG_ECC; 1363 } 1364 1365 function GetAesGenerateProperties() { 1366 let properties: HuksProperties[] = [ 1367 { 1368 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 1369 value: huks.HuksKeyAlg.HUKS_ALG_AES 1370 }, 1371 { 1372 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 1373 value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128 1374 }, 1375 { 1376 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 1377 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | 1378 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT 1379 } 1380 ]; 1381 return properties; 1382 } 1383 1384 async function GenerateAesKey() { 1385 let genProperties = GetAesGenerateProperties(); 1386 let options: huks.HuksOptions = { 1387 properties: genProperties 1388 } 1389 await huks.generateKeyItem(aesKeyAlias, options).then((data) => { 1390 console.log("generateKeyItem success"); 1391 }).catch((error: BusinessError) => { 1392 console.log("generateKeyItem failed"); 1393 }) 1394 } 1395 ``` 1396 13973. Use **huks.initSession** and **huks.finishSession** to encrypt data. 1398 1399 ```ts 1400 let plainText = '123456'; 1401 1402 function StringToUint8Array(str: string) { 1403 let arr: number[] = []; 1404 for (let i = 0, j = str.length; i < j; ++i) { 1405 arr.push(str.charCodeAt(i)); 1406 } 1407 return new Uint8Array(arr); 1408 } 1409 1410 function GetAesEncryptProperties() { 1411 let properties: HuksProperties1[] = [ 1412 { 1413 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 1414 value: huks.HuksKeyAlg.HUKS_ALG_AES 1415 }, 1416 { 1417 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 1418 value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128 1419 }, 1420 { 1421 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 1422 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT 1423 }, 1424 { 1425 tag: huks.HuksTag.HUKS_TAG_PADDING, 1426 value: huks.HuksKeyPadding.HUKS_PADDING_PKCS7 1427 }, 1428 { 1429 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 1430 value: huks.HuksCipherMode.HUKS_MODE_CBC 1431 }, 1432 { 1433 tag: huks.HuksTag.HUKS_TAG_IV, 1434 value: StringToUint8Array(IV) 1435 } 1436 ] 1437 return properties; 1438 } 1439 1440 async function EncryptData() { 1441 let encryptProperties = GetAesEncryptProperties(); 1442 let options: huks.HuksOptions = { 1443 properties: encryptProperties, 1444 inData: StringToUint8Array(plainText) 1445 } 1446 await huks.initSession(aesKeyAlias, options).then((data) => { 1447 handle = data.handle; 1448 }).catch((error: BusinessError) => { 1449 console.log("initSession failed"); 1450 }) 1451 await huks.finishSession(handle, options).then((data) => { 1452 console.log("finishSession success"); 1453 }).catch((error: BusinessError) => { 1454 console.log("finishSession failed"); 1455 }) 1456 } 1457 1458 ``` 1459