• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Key Derivation (C/C++)
2
3
4This topic walks you through on how to derive a 256-bit key using HKDF. For details about the scenarios and supported algorithms, see [Supported Algorithms](huks-key-generation-overview.md#supported-algorithms).
5
6
7## How to Develop
8
9**Key Generation**
10
111. Set the key alias.
12
132. Initialize the key property set. The optional parameter **OH_HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG** specifies how a derived key is stored.
14   - **OH_HUKS_STORAGE_ONLY_USED_IN_HUKS**: The key is stored and managed by HUKS.
15   - **OH_HUKS_STORAGE_KEY_EXPORT_ALLOWED** (default): The key is directly exported to the service and not managed by HUKS.
16
173. Use **OH_Huks_GenerateKeyItem** to generate a key. For details, see [Key Generation](huks-key-generation-overview.md).
18
19Alternatively, you can [import a key](huks-key-import-overview.md).
20
21**Key Derivation**
22
231. Obtain the key alias and set the **HuksOptions** parameter.
24
25   You are advised to pass in [OH_Huks_KeyStorageType](../../reference/apis-universal-keystore-kit/_huks_type_api.md#oh_huks_keystoragetype), which can be any of the following values:
26
27   - **OH_HUKS_STORAGE_ONLY_USED_IN_HUKS**: The key is used only in HUKS.
28   - **OH_HUKS_STORAGE_KEY_EXPORT_ALLOWED**: The key is directly exported and is not stored in HUKS.
29   - If this parameter is not specified, the key can be stored in HUKS and exported by default, which poses security risks and is not recommended.
30
312. Use [OH_Huks_InitSession](../../reference/apis-universal-keystore-kit/_huks_key_api.md#oh_huks_initsession) to initialize a key session. The session handle is returned after the initialization.
32
333. Use [OH_Huks_UpdateSession](../../reference/apis-universal-keystore-kit/_huks_key_api.md#oh_huks_updatesession)n to process data.
34
354. Use [OH_Huks_FinishSession](../../reference/apis-universal-keystore-kit/_huks_key_api.md#oh_huks_finishsession) to derive a key.
36
37**Key Deletion**
38
39Use **OH_Huks_DeleteKeyItem** to delete the key that is not required. For details, see [Deleting a Key](huks-delete-key-ndk.md).
40
41```c++
42#include "huks/native_huks_api.h"
43#include "huks/native_huks_param.h"
44#include <string.h>
45OH_Huks_Result InitParamSet(
46    struct OH_Huks_ParamSet **paramSet,
47    const struct OH_Huks_Param *params,
48    uint32_t paramCount)
49{
50    OH_Huks_Result ret = OH_Huks_InitParamSet(paramSet);
51    if (ret.errorCode != OH_HUKS_SUCCESS) {
52        return ret;
53    }
54    ret = OH_Huks_AddParams(*paramSet, params, paramCount);
55    if (ret.errorCode != OH_HUKS_SUCCESS) {
56        OH_Huks_FreeParamSet(paramSet);
57        return ret;
58    }
59    ret = OH_Huks_BuildParamSet(paramSet);
60    if (ret.errorCode != OH_HUKS_SUCCESS) {
61        OH_Huks_FreeParamSet(paramSet);
62        return ret;
63    }
64    return ret;
65}
66static const uint32_t DERIVE_KEY_SIZE_32 = 32;
67static struct OH_Huks_Blob g_deriveKeyAlias = {
68    (uint32_t)strlen("test_derive"),
69    (uint8_t *)"test_derive"
70};
71static struct OH_Huks_Param g_genDeriveParams[] = {
72    {
73        .tag =  OH_HUKS_TAG_ALGORITHM,
74        .uint32Param = OH_HUKS_ALG_AES
75    }, {
76        .tag =  OH_HUKS_TAG_PURPOSE,
77        .uint32Param = OH_HUKS_KEY_PURPOSE_DERIVE
78    }, {
79        .tag =  OH_HUKS_TAG_DIGEST,
80        .uint32Param = OH_HUKS_DIGEST_SHA256
81    }, {
82        .tag =  OH_HUKS_TAG_KEY_SIZE,
83        .uint32Param = OH_HUKS_AES_KEY_SIZE_256
84    }
85};
86static struct OH_Huks_Param g_hkdfParams[] = {
87    {
88        .tag =  OH_HUKS_TAG_ALGORITHM,
89        .uint32Param = OH_HUKS_ALG_HKDF
90    }, {
91        .tag =  OH_HUKS_TAG_PURPOSE,
92        .uint32Param = OH_HUKS_KEY_PURPOSE_DERIVE
93    }, {
94        .tag =  OH_HUKS_TAG_DIGEST,
95        .uint32Param = OH_HUKS_DIGEST_SHA256
96    }, {
97        .tag =  OH_HUKS_TAG_DERIVE_KEY_SIZE,
98        .uint32Param = DERIVE_KEY_SIZE_32
99    }
100};
101static struct OH_Huks_Param g_hkdfFinishParams[] = {
102    {
103        .tag =  OH_HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG,
104        .uint32Param = OH_HUKS_STORAGE_ONLY_USED_IN_HUKS
105    }, {
106        .tag =  OH_HUKS_TAG_KEY_ALIAS,
107        .blob = g_deriveKeyAlias
108    }, {
109        .tag =  OH_HUKS_TAG_ALGORITHM,
110        .uint32Param = OH_HUKS_ALG_HKDF
111    }, {
112        .tag =  OH_HUKS_TAG_KEY_SIZE,
113        .uint32Param = DERIVE_KEY_SIZE_32
114    }, {
115        .tag =  OH_HUKS_TAG_PURPOSE,
116        .uint32Param = OH_HUKS_KEY_PURPOSE_DERIVE
117    }, {
118        .tag =  OH_HUKS_TAG_DIGEST,
119        .uint32Param = OH_HUKS_DIGEST_SHA256
120    }
121};
122static const uint32_t COMMON_SIZE = 2048;
123static const char *g_deriveInData = "Hks_HKDF_Derive_Test_00000000000000000000000000000000000000000000000000000000000"
124                                    "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
125                                    "0000000000000000000000000000000000000000000000000000000000000000000000000_string";
126static napi_value DeriveKey(napi_env env, napi_callback_info info)
127{
128    struct OH_Huks_Blob genAlias = {
129        (uint32_t)strlen("test_signVerify"),
130        (uint8_t *)"test_signVerify"
131    };
132    struct OH_Huks_Blob inData = {
133        (uint32_t)strlen(g_deriveInData),
134        (uint8_t *)g_deriveInData
135    };
136    struct OH_Huks_ParamSet *genParamSet = nullptr;
137    struct OH_Huks_ParamSet *hkdfParamSet = nullptr;
138    struct OH_Huks_ParamSet *hkdfFinishParamSet = nullptr;
139    OH_Huks_Result ohResult;
140    do {
141        ohResult = InitParamSet(&genParamSet, g_genDeriveParams, sizeof(g_genDeriveParams) / sizeof(OH_Huks_Param));
142        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
143            break;
144        }
145
146        ohResult = InitParamSet(&hkdfParamSet, g_hkdfParams, sizeof(g_hkdfParams) / sizeof(OH_Huks_Param));
147        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
148           break;
149        }
150
151        // finish paramset
152        ohResult = InitParamSet(&hkdfFinishParamSet, g_hkdfFinishParams, sizeof(g_hkdfFinishParams) / sizeof(OH_Huks_Param));
153        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
154            break;
155        }
156
157        /* 1. Generate Key */
158        ohResult = OH_Huks_GenerateKeyItem(&genAlias, genParamSet, nullptr);
159        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
160            break;
161        }
162        /* 2. Derive */
163        // Init
164        uint8_t handleD[sizeof(uint64_t)] = {0};
165        struct OH_Huks_Blob handleDerive = { sizeof(uint64_t), handleD };
166        ohResult = OH_Huks_InitSession(&genAlias, hkdfParamSet, &handleDerive, nullptr);
167        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
168            break;
169        }
170        // Update
171        uint8_t tmpOut[COMMON_SIZE] = {0};
172        struct OH_Huks_Blob outData = { COMMON_SIZE, tmpOut };
173        ohResult = OH_Huks_UpdateSession(&handleDerive, hkdfParamSet, &inData, &outData);
174        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
175            break;
176        }
177        // Finish
178        uint8_t outDataD[COMMON_SIZE] = {0};
179        struct OH_Huks_Blob outDataDerive = { COMMON_SIZE, outDataD };
180        ohResult = OH_Huks_FinishSession(&handleDerive, hkdfFinishParamSet, &inData, &outDataDerive);
181    } while (0);
182    (void)OH_Huks_DeleteKeyItem(&genAlias, nullptr);
183    (void)OH_Huks_DeleteKeyItem(&g_deriveKeyAlias, nullptr);
184    OH_Huks_FreeParamSet(&genParamSet);
185    OH_Huks_FreeParamSet(&hkdfParamSet);
186    OH_Huks_FreeParamSet(&hkdfFinishParamSet);
187
188    napi_value ret;
189    napi_create_int32(env, ohResult.errorCode, &ret);
190    return ret;
191}
192```
193