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![huks_architect](./figures/HUKS-architecture.png)
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  ![CertChain format](figures/HUKS-CertChain.png)
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  ![KeyBlob format](figures/HUKS-KeyBlob.png)
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