1e41f4b71Sopenharmony_ci# Key Derivation (C/C++) 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ciThis 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). 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ci## Add the dynamic library in the CMake script. 7e41f4b71Sopenharmony_ci```txt 8e41f4b71Sopenharmony_ci target_link_libraries(entry PUBLIC libhuks_ndk.z.so) 9e41f4b71Sopenharmony_ci``` 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ci## How to Develop 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ci**Key Generation** 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ci1. Set the key alias. 16e41f4b71Sopenharmony_ci 17e41f4b71Sopenharmony_ci2. Initialize the key property set. You can set **OH_HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG** (optional) to specify how the key derived from this key is managed. 18e41f4b71Sopenharmony_ci 19e41f4b71Sopenharmony_ci - If this tag is set to **OH_HUKS_STORAGE_ONLY_USED_IN_HUKS**, the derived key is managed by HUKS. That is, the derived key is always in a secure environment throughout its lifecycle. 20e41f4b71Sopenharmony_ci 21e41f4b71Sopenharmony_ci - If this tag is set to **OH_HUKS_STORAGE_KEY_EXPORT_ALLOWED**, the derived key will be returned to the caller for management. That is, the service side ensures the key security. 22e41f4b71Sopenharmony_ci 23e41f4b71Sopenharmony_ci - If this tag is not set, the derived key can be either managed by HUKS or returned to the caller for management. The key protection mode can be set in the subsequent key derivation on the service side. 24e41f4b71Sopenharmony_ci 25e41f4b71Sopenharmony_ci3. Use **OH_Huks_GenerateKeyItem** to generate a key. For details, see [Key Generation](huks-key-generation-overview.md). 26e41f4b71Sopenharmony_ci 27e41f4b71Sopenharmony_ciAlternatively, you can [import a key](huks-key-import-overview.md). 28e41f4b71Sopenharmony_ci 29e41f4b71Sopenharmony_ci**Key Derivation** 30e41f4b71Sopenharmony_ci 31e41f4b71Sopenharmony_ci1. Obtain the key alias and set the **HuksOptions** parameter. 32e41f4b71Sopenharmony_ci 33e41f4b71Sopenharmony_ci You can set **OH_HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG** to specify how the derived key is managed. 34e41f4b71Sopenharmony_ci 35e41f4b71Sopenharmony_ci | Key Generation| Key Derivation| Specifications| 36e41f4b71Sopenharmony_ci | -------- | -------- | -------- | 37e41f4b71Sopenharmony_ci | OH_HUKS_STORAGE_ONLY_USED_IN_HUKS | OH_HUKS_STORAGE_ONLY_USED_IN_HUKS | The key is managed by HUKS.| 38e41f4b71Sopenharmony_ci | OH_HUKS_STORAGE_KEY_EXPORT_ALLOWED | OH_HUKS_STORAGE_KEY_EXPORT_ALLOWED | The key is returned to the caller for management.| 39e41f4b71Sopenharmony_ci | The tag is not set.| OH_HUKS_STORAGE_ONLY_USED_IN_HUKS | The key is managed by HUKS.| 40e41f4b71Sopenharmony_ci | The tag is not set.| OH_HUKS_STORAGE_KEY_EXPORT_ALLOWED | The key is returned to the caller for management.| 41e41f4b71Sopenharmony_ci | The tag is not set.| The tag is not set.| The key is returned to the caller for management.| 42e41f4b71Sopenharmony_ci 43e41f4b71Sopenharmony_ci >**NOTE**<br>The tag value set in key derivation should not conflict with the tag value set in key generation. The above table lists only valid settings. 44e41f4b71Sopenharmony_ci 45e41f4b71Sopenharmony_ci2. 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. 46e41f4b71Sopenharmony_ci 47e41f4b71Sopenharmony_ci3. Use [OH_Huks_UpdateSession](../../reference/apis-universal-keystore-kit/_huks_key_api.md#oh_huks_updatesession)n to process data. 48e41f4b71Sopenharmony_ci 49e41f4b71Sopenharmony_ci4. Use [OH_Huks_FinishSession](../../reference/apis-universal-keystore-kit/_huks_key_api.md#oh_huks_finishsession) to derive a key. 50e41f4b71Sopenharmony_ci 51e41f4b71Sopenharmony_ci**Key Deletion** 52e41f4b71Sopenharmony_ci 53e41f4b71Sopenharmony_ciUse **OH_Huks_DeleteKeyItem** to delete the key that is not required. For details, see [Deleting a Key](huks-delete-key-ndk.md). 54e41f4b71Sopenharmony_ci 55e41f4b71Sopenharmony_ci```c++ 56e41f4b71Sopenharmony_ci#include "huks/native_huks_api.h" 57e41f4b71Sopenharmony_ci#include "huks/native_huks_param.h" 58e41f4b71Sopenharmony_ci#include <string.h> 59e41f4b71Sopenharmony_ciOH_Huks_Result InitParamSet( 60e41f4b71Sopenharmony_ci struct OH_Huks_ParamSet **paramSet, 61e41f4b71Sopenharmony_ci const struct OH_Huks_Param *params, 62e41f4b71Sopenharmony_ci uint32_t paramCount) 63e41f4b71Sopenharmony_ci{ 64e41f4b71Sopenharmony_ci OH_Huks_Result ret = OH_Huks_InitParamSet(paramSet); 65e41f4b71Sopenharmony_ci if (ret.errorCode != OH_HUKS_SUCCESS) { 66e41f4b71Sopenharmony_ci return ret; 67e41f4b71Sopenharmony_ci } 68e41f4b71Sopenharmony_ci ret = OH_Huks_AddParams(*paramSet, params, paramCount); 69e41f4b71Sopenharmony_ci if (ret.errorCode != OH_HUKS_SUCCESS) { 70e41f4b71Sopenharmony_ci OH_Huks_FreeParamSet(paramSet); 71e41f4b71Sopenharmony_ci return ret; 72e41f4b71Sopenharmony_ci } 73e41f4b71Sopenharmony_ci ret = OH_Huks_BuildParamSet(paramSet); 74e41f4b71Sopenharmony_ci if (ret.errorCode != OH_HUKS_SUCCESS) { 75e41f4b71Sopenharmony_ci OH_Huks_FreeParamSet(paramSet); 76e41f4b71Sopenharmony_ci return ret; 77e41f4b71Sopenharmony_ci } 78e41f4b71Sopenharmony_ci return ret; 79e41f4b71Sopenharmony_ci} 80e41f4b71Sopenharmony_cistatic const uint32_t DERIVE_KEY_SIZE_32 = 32; 81e41f4b71Sopenharmony_cistatic struct OH_Huks_Blob g_deriveKeyAlias = { 82e41f4b71Sopenharmony_ci (uint32_t)strlen("test_derive"), 83e41f4b71Sopenharmony_ci (uint8_t *)"test_derive" 84e41f4b71Sopenharmony_ci}; 85e41f4b71Sopenharmony_cistatic struct OH_Huks_Param g_genDeriveParams[] = { 86e41f4b71Sopenharmony_ci { 87e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_ALGORITHM, 88e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_ALG_AES 89e41f4b71Sopenharmony_ci }, { 90e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_PURPOSE, 91e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_KEY_PURPOSE_DERIVE 92e41f4b71Sopenharmony_ci }, { 93e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_DIGEST, 94e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_DIGEST_SHA256 95e41f4b71Sopenharmony_ci }, { 96e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_KEY_SIZE, 97e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_AES_KEY_SIZE_256 98e41f4b71Sopenharmony_ci } 99e41f4b71Sopenharmony_ci}; 100e41f4b71Sopenharmony_cistatic struct OH_Huks_Param g_hkdfParams[] = { 101e41f4b71Sopenharmony_ci { 102e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_ALGORITHM, 103e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_ALG_HKDF 104e41f4b71Sopenharmony_ci }, { 105e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_PURPOSE, 106e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_KEY_PURPOSE_DERIVE 107e41f4b71Sopenharmony_ci }, { 108e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_DIGEST, 109e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_DIGEST_SHA256 110e41f4b71Sopenharmony_ci }, { 111e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_DERIVE_KEY_SIZE, 112e41f4b71Sopenharmony_ci .uint32Param = DERIVE_KEY_SIZE_32 113e41f4b71Sopenharmony_ci } 114e41f4b71Sopenharmony_ci}; 115e41f4b71Sopenharmony_cistatic struct OH_Huks_Param g_hkdfFinishParams[] = { 116e41f4b71Sopenharmony_ci { 117e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG, 118e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_STORAGE_ONLY_USED_IN_HUKS 119e41f4b71Sopenharmony_ci }, { 120e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_KEY_ALIAS, 121e41f4b71Sopenharmony_ci .blob = g_deriveKeyAlias 122e41f4b71Sopenharmony_ci }, { 123e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_ALGORITHM, 124e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_ALG_HKDF 125e41f4b71Sopenharmony_ci }, { 126e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_KEY_SIZE, 127e41f4b71Sopenharmony_ci .uint32Param = DERIVE_KEY_SIZE_32 128e41f4b71Sopenharmony_ci }, { 129e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_PURPOSE, 130e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_KEY_PURPOSE_DERIVE 131e41f4b71Sopenharmony_ci }, { 132e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_DIGEST, 133e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_DIGEST_SHA256 134e41f4b71Sopenharmony_ci } 135e41f4b71Sopenharmony_ci}; 136e41f4b71Sopenharmony_cistatic const uint32_t COMMON_SIZE = 2048; 137e41f4b71Sopenharmony_cistatic const char *g_deriveInData = "Hks_HKDF_Derive_Test_00000000000000000000000000000000000000000000000000000000000" 138e41f4b71Sopenharmony_ci "00000000000000000000000000000000000000000000000000000000000000000000000000000000" 139e41f4b71Sopenharmony_ci "0000000000000000000000000000000000000000000000000000000000000000000000000_string"; 140e41f4b71Sopenharmony_cistatic napi_value DeriveKey(napi_env env, napi_callback_info info) 141e41f4b71Sopenharmony_ci{ 142e41f4b71Sopenharmony_ci struct OH_Huks_Blob genAlias = { 143e41f4b71Sopenharmony_ci (uint32_t)strlen("test_signVerify"), 144e41f4b71Sopenharmony_ci (uint8_t *)"test_signVerify" 145e41f4b71Sopenharmony_ci }; 146e41f4b71Sopenharmony_ci struct OH_Huks_Blob inData = { 147e41f4b71Sopenharmony_ci (uint32_t)strlen(g_deriveInData), 148e41f4b71Sopenharmony_ci (uint8_t *)g_deriveInData 149e41f4b71Sopenharmony_ci }; 150e41f4b71Sopenharmony_ci struct OH_Huks_ParamSet *genParamSet = nullptr; 151e41f4b71Sopenharmony_ci struct OH_Huks_ParamSet *hkdfParamSet = nullptr; 152e41f4b71Sopenharmony_ci struct OH_Huks_ParamSet *hkdfFinishParamSet = nullptr; 153e41f4b71Sopenharmony_ci OH_Huks_Result ohResult; 154e41f4b71Sopenharmony_ci do { 155e41f4b71Sopenharmony_ci ohResult = InitParamSet(&genParamSet, g_genDeriveParams, sizeof(g_genDeriveParams) / sizeof(OH_Huks_Param)); 156e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 157e41f4b71Sopenharmony_ci break; 158e41f4b71Sopenharmony_ci } 159e41f4b71Sopenharmony_ci 160e41f4b71Sopenharmony_ci ohResult = InitParamSet(&hkdfParamSet, g_hkdfParams, sizeof(g_hkdfParams) / sizeof(OH_Huks_Param)); 161e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 162e41f4b71Sopenharmony_ci break; 163e41f4b71Sopenharmony_ci } 164e41f4b71Sopenharmony_ci 165e41f4b71Sopenharmony_ci // finish paramset 166e41f4b71Sopenharmony_ci ohResult = InitParamSet(&hkdfFinishParamSet, g_hkdfFinishParams, sizeof(g_hkdfFinishParams) / sizeof(OH_Huks_Param)); 167e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 168e41f4b71Sopenharmony_ci break; 169e41f4b71Sopenharmony_ci } 170e41f4b71Sopenharmony_ci 171e41f4b71Sopenharmony_ci /* 1. Generate Key */ 172e41f4b71Sopenharmony_ci ohResult = OH_Huks_GenerateKeyItem(&genAlias, genParamSet, nullptr); 173e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 174e41f4b71Sopenharmony_ci break; 175e41f4b71Sopenharmony_ci } 176e41f4b71Sopenharmony_ci /* 2. Derive */ 177e41f4b71Sopenharmony_ci // Init 178e41f4b71Sopenharmony_ci uint8_t handleD[sizeof(uint64_t)] = {0}; 179e41f4b71Sopenharmony_ci struct OH_Huks_Blob handleDerive = { sizeof(uint64_t), handleD }; 180e41f4b71Sopenharmony_ci ohResult = OH_Huks_InitSession(&genAlias, hkdfParamSet, &handleDerive, nullptr); 181e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 182e41f4b71Sopenharmony_ci break; 183e41f4b71Sopenharmony_ci } 184e41f4b71Sopenharmony_ci // Update 185e41f4b71Sopenharmony_ci uint8_t tmpOut[COMMON_SIZE] = {0}; 186e41f4b71Sopenharmony_ci struct OH_Huks_Blob outData = { COMMON_SIZE, tmpOut }; 187e41f4b71Sopenharmony_ci ohResult = OH_Huks_UpdateSession(&handleDerive, hkdfParamSet, &inData, &outData); 188e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 189e41f4b71Sopenharmony_ci break; 190e41f4b71Sopenharmony_ci } 191e41f4b71Sopenharmony_ci // Finish 192e41f4b71Sopenharmony_ci uint8_t outDataD[COMMON_SIZE] = {0}; 193e41f4b71Sopenharmony_ci struct OH_Huks_Blob outDataDerive = { COMMON_SIZE, outDataD }; 194e41f4b71Sopenharmony_ci ohResult = OH_Huks_FinishSession(&handleDerive, hkdfFinishParamSet, &inData, &outDataDerive); 195e41f4b71Sopenharmony_ci } while (0); 196e41f4b71Sopenharmony_ci (void)OH_Huks_DeleteKeyItem(&genAlias, nullptr); 197e41f4b71Sopenharmony_ci (void)OH_Huks_DeleteKeyItem(&g_deriveKeyAlias, nullptr); 198e41f4b71Sopenharmony_ci OH_Huks_FreeParamSet(&genParamSet); 199e41f4b71Sopenharmony_ci OH_Huks_FreeParamSet(&hkdfParamSet); 200e41f4b71Sopenharmony_ci OH_Huks_FreeParamSet(&hkdfFinishParamSet); 201e41f4b71Sopenharmony_ci 202e41f4b71Sopenharmony_ci napi_value ret; 203e41f4b71Sopenharmony_ci napi_create_int32(env, ohResult.errorCode, &ret); 204e41f4b71Sopenharmony_ci return ret; 205e41f4b71Sopenharmony_ci} 206e41f4b71Sopenharmony_ci``` 207