1e41f4b71Sopenharmony_ci# Key Agreement (C/C++) 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ciThis topic walks you through on how to agree on an ECDH key that is used only in HUKS. 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_ciGenerate an asymmetric key for device A and device B each. For details, see [Key Generation](huks-key-generation-overview.md) or [Key Import](huks-key-import-overview.md). 16e41f4b71Sopenharmony_ci 17e41f4b71Sopenharmony_ciWhen generating a key, you can set **OH_HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG** (optional) to specify how the shared secret generated from this key through key agreement is managed. 18e41f4b71Sopenharmony_ci 19e41f4b71Sopenharmony_ci- If this tag is set to **OH_HUKS_STORAGE_ONLY_USED_IN_HUKS**, the shared secret is managed by HUKS. That is, the shared secret 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 shared secret generated 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 shared secret generated can be either managed by HUKS or returned to the caller for management. The key protection mode can be set in the subsequent key agreement on the service side. 24e41f4b71Sopenharmony_ci 25e41f4b71Sopenharmony_ci**Key Export** 26e41f4b71Sopenharmony_ci 27e41f4b71Sopenharmony_ciExport the public key of the asymmetric key pair of device A and device B. For details, see [Key Export](huks-export-key-arkts.md). 28e41f4b71Sopenharmony_ci 29e41f4b71Sopenharmony_ci**Key Agreement** 30e41f4b71Sopenharmony_ci 31e41f4b71Sopenharmony_ciPerform key agreement using the public key of the peer device and private key of the local device (that is, public key of device B and private key of device A for device A, and public key of device A and private key of device B for device B) to produce a shared secret. 32e41f4b71Sopenharmony_ci 33e41f4b71Sopenharmony_ciDuring key agreement, you can set **OH_HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG** (optional) to specify how the shared secret generated is managed. 34e41f4b71Sopenharmony_ci 35e41f4b71Sopenharmony_ci| Key Generation| Key Agreement| 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 agreement should not conflict with the tag value set in key generation. The above table lists only valid settings. 44e41f4b71Sopenharmony_ci 45e41f4b71Sopenharmony_ci**Key Deletion** 46e41f4b71Sopenharmony_ci 47e41f4b71Sopenharmony_ciDelete the keys from device A and device B when the keys are not required. For details, see [Deleting a Key](huks-delete-key-ndk.md). 48e41f4b71Sopenharmony_ci 49e41f4b71Sopenharmony_ci```c++ 50e41f4b71Sopenharmony_ci#include "huks/native_huks_api.h" 51e41f4b71Sopenharmony_ci#include "huks/native_huks_param.h" 52e41f4b71Sopenharmony_ci#include <string.h> 53e41f4b71Sopenharmony_ci/* Initialize parameters. */ 54e41f4b71Sopenharmony_ciOH_Huks_Result InitParamSet( 55e41f4b71Sopenharmony_ci struct OH_Huks_ParamSet **paramSet, 56e41f4b71Sopenharmony_ci const struct OH_Huks_Param *params, 57e41f4b71Sopenharmony_ci uint32_t paramCount) 58e41f4b71Sopenharmony_ci{ 59e41f4b71Sopenharmony_ci OH_Huks_Result ret = OH_Huks_InitParamSet(paramSet); 60e41f4b71Sopenharmony_ci if (ret.errorCode != OH_HUKS_SUCCESS) { 61e41f4b71Sopenharmony_ci return ret; 62e41f4b71Sopenharmony_ci } 63e41f4b71Sopenharmony_ci ret = OH_Huks_AddParams(*paramSet, params, paramCount); 64e41f4b71Sopenharmony_ci if (ret.errorCode != OH_HUKS_SUCCESS) { 65e41f4b71Sopenharmony_ci OH_Huks_FreeParamSet(paramSet); 66e41f4b71Sopenharmony_ci return ret; 67e41f4b71Sopenharmony_ci } 68e41f4b71Sopenharmony_ci ret = OH_Huks_BuildParamSet(paramSet); 69e41f4b71Sopenharmony_ci if (ret.errorCode != OH_HUKS_SUCCESS) { 70e41f4b71Sopenharmony_ci OH_Huks_FreeParamSet(paramSet); 71e41f4b71Sopenharmony_ci return ret; 72e41f4b71Sopenharmony_ci } 73e41f4b71Sopenharmony_ci return ret; 74e41f4b71Sopenharmony_ci} 75e41f4b71Sopenharmony_cistatic const uint32_t IV_SIZE = 16; 76e41f4b71Sopenharmony_cistatic uint8_t IV[IV_SIZE] = { 0 }; // this is a test value, for real use the iv should be different every time 77e41f4b71Sopenharmony_cistatic struct OH_Huks_Blob g_keyAliasFinal1001 = { 78e41f4b71Sopenharmony_ci (uint32_t)strlen("HksECDHAgreeKeyAliasTest001_1_final"), 79e41f4b71Sopenharmony_ci (uint8_t *)"HksECDHAgreeKeyAliasTest001_1_final" 80e41f4b71Sopenharmony_ci}; 81e41f4b71Sopenharmony_ci/* Set the key parameter set. */ 82e41f4b71Sopenharmony_cistatic struct OH_Huks_Param g_genAgreeParams[] = { 83e41f4b71Sopenharmony_ci { 84e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_ALGORITHM, 85e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_ALG_ECC 86e41f4b71Sopenharmony_ci }, { 87e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_PURPOSE, 88e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_KEY_PURPOSE_AGREE 89e41f4b71Sopenharmony_ci }, { 90e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_KEY_SIZE, 91e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_ECC_KEY_SIZE_256 92e41f4b71Sopenharmony_ci }, { 93e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_DIGEST, 94e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_DIGEST_NONE 95e41f4b71Sopenharmony_ci } 96e41f4b71Sopenharmony_ci}; 97e41f4b71Sopenharmony_cistatic struct OH_Huks_Param g_agreeParamsInit01[] = { 98e41f4b71Sopenharmony_ci { 99e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_ALGORITHM, 100e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_ALG_ECDH 101e41f4b71Sopenharmony_ci }, { 102e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_PURPOSE, 103e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_KEY_PURPOSE_AGREE 104e41f4b71Sopenharmony_ci }, { 105e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_KEY_SIZE, 106e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_ECC_KEY_SIZE_256 107e41f4b71Sopenharmony_ci } 108e41f4b71Sopenharmony_ci}; 109e41f4b71Sopenharmony_cistatic struct OH_Huks_Param g_agreeParamsFinish01[] = { 110e41f4b71Sopenharmony_ci { 111e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG, 112e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_STORAGE_ONLY_USED_IN_HUKS 113e41f4b71Sopenharmony_ci }, { 114e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_ALGORITHM, 115e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_ALG_AES 116e41f4b71Sopenharmony_ci }, { 117e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_KEY_SIZE, 118e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_AES_KEY_SIZE_256 119e41f4b71Sopenharmony_ci }, { 120e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_PURPOSE, 121e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_KEY_PURPOSE_AGREE 122e41f4b71Sopenharmony_ci }, { 123e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_KEY_ALIAS, 124e41f4b71Sopenharmony_ci .blob = g_keyAliasFinal1001 125e41f4b71Sopenharmony_ci }, { 126e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_PADDING, 127e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_PADDING_NONE 128e41f4b71Sopenharmony_ci }, { 129e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_BLOCK_MODE, 130e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_MODE_CBC 131e41f4b71Sopenharmony_ci } 132e41f4b71Sopenharmony_ci}; 133e41f4b71Sopenharmony_cistatic struct OH_Huks_Blob g_keyAliasFinal2001 = { 134e41f4b71Sopenharmony_ci (uint32_t)strlen("HksECDHAgreeKeyAliasTest001_2_final"), 135e41f4b71Sopenharmony_ci (uint8_t *)"HksECDHAgreeKeyAliasTest001_2_final" 136e41f4b71Sopenharmony_ci}; 137e41f4b71Sopenharmony_cistatic struct OH_Huks_Param g_agreeParamsInit02[] = { 138e41f4b71Sopenharmony_ci { 139e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_ALGORITHM, 140e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_ALG_ECDH 141e41f4b71Sopenharmony_ci }, { 142e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_PURPOSE, 143e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_KEY_PURPOSE_AGREE 144e41f4b71Sopenharmony_ci }, { 145e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_KEY_SIZE, 146e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_ECC_KEY_SIZE_256 147e41f4b71Sopenharmony_ci } 148e41f4b71Sopenharmony_ci}; 149e41f4b71Sopenharmony_cistatic struct OH_Huks_Param g_agreeParamsFinish02[] = { 150e41f4b71Sopenharmony_ci { 151e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG, 152e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_STORAGE_ONLY_USED_IN_HUKS 153e41f4b71Sopenharmony_ci }, { 154e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_ALGORITHM, 155e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_ALG_AES 156e41f4b71Sopenharmony_ci }, { 157e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_KEY_SIZE, 158e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_AES_KEY_SIZE_256 159e41f4b71Sopenharmony_ci }, { 160e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_PURPOSE, 161e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_KEY_PURPOSE_DERIVE 162e41f4b71Sopenharmony_ci }, { 163e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_KEY_ALIAS, 164e41f4b71Sopenharmony_ci .blob = g_keyAliasFinal2001 165e41f4b71Sopenharmony_ci }, { 166e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_PADDING, 167e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_PADDING_NONE 168e41f4b71Sopenharmony_ci }, { 169e41f4b71Sopenharmony_ci .tag = OH_HUKS_TAG_BLOCK_MODE, 170e41f4b71Sopenharmony_ci .uint32Param = OH_HUKS_MODE_CBC 171e41f4b71Sopenharmony_ci } 172e41f4b71Sopenharmony_ci}; 173e41f4b71Sopenharmony_cistatic const uint32_t ECDH_COMMON_SIZE = 1024; 174e41f4b71Sopenharmony_cistatic struct OH_Huks_Blob g_keyAlias01001 = { 175e41f4b71Sopenharmony_ci (uint32_t)strlen("HksECDHAgreeKeyAliasTest001_1"), 176e41f4b71Sopenharmony_ci (uint8_t *)"HksECDHAgreeKeyAliasTest001_1" 177e41f4b71Sopenharmony_ci}; 178e41f4b71Sopenharmony_cistatic struct OH_Huks_Blob g_keyAlias02001 = { 179e41f4b71Sopenharmony_ci (uint32_t)strlen("HksECDHAgreeKeyAliasTest001_2"), 180e41f4b71Sopenharmony_ci (uint8_t *)"HksECDHAgreeKeyAliasTest001_2" 181e41f4b71Sopenharmony_ci}; 182e41f4b71Sopenharmony_ciOH_Huks_Result MallocAndCheckBlobData( 183e41f4b71Sopenharmony_ci struct OH_Huks_Blob *blob, 184e41f4b71Sopenharmony_ci const uint32_t blobSize) 185e41f4b71Sopenharmony_ci{ 186e41f4b71Sopenharmony_ci struct OH_Huks_Result ret; 187e41f4b71Sopenharmony_ci ret.errorCode = OH_HUKS_SUCCESS; 188e41f4b71Sopenharmony_ci blob->data = (uint8_t *)malloc(blobSize); 189e41f4b71Sopenharmony_ci if (blob->data == NULL) { 190e41f4b71Sopenharmony_ci ret.errorCode = OH_HUKS_ERR_CODE_INTERNAL_ERROR; 191e41f4b71Sopenharmony_ci } 192e41f4b71Sopenharmony_ci return ret; 193e41f4b71Sopenharmony_ci} 194e41f4b71Sopenharmony_ci/* Export a key. */ 195e41f4b71Sopenharmony_ciOH_Huks_Result HksEcdhAgreeExport(const struct OH_Huks_Blob *keyAlias1, const struct OH_Huks_Blob *keyAlias2, 196e41f4b71Sopenharmony_ci struct OH_Huks_Blob *publicKey1, struct OH_Huks_Blob *publicKey2, const struct OH_Huks_ParamSet *genParamSet) 197e41f4b71Sopenharmony_ci{ 198e41f4b71Sopenharmony_ci OH_Huks_Result ret = OH_Huks_ExportPublicKeyItem(keyAlias1, genParamSet, publicKey1); 199e41f4b71Sopenharmony_ci if (ret.errorCode != OH_HUKS_SUCCESS) { 200e41f4b71Sopenharmony_ci return ret; 201e41f4b71Sopenharmony_ci } 202e41f4b71Sopenharmony_ci ret = OH_Huks_ExportPublicKeyItem(keyAlias2, genParamSet, publicKey2); 203e41f4b71Sopenharmony_ci if (ret.errorCode != OH_HUKS_SUCCESS) { 204e41f4b71Sopenharmony_ci return ret; 205e41f4b71Sopenharmony_ci } 206e41f4b71Sopenharmony_ci return ret; 207e41f4b71Sopenharmony_ci} 208e41f4b71Sopenharmony_cistatic const char *g_inData = "Hks_ECDH_Agree_Test_000000000000000000000000000000000000000000000000000000000000" 209e41f4b71Sopenharmony_ci "00000000000000000000000000000000000000000000000000000000000000000000000000000000" 210e41f4b71Sopenharmony_ci "0000000000000000000000000000000000000000000000000000000000000000000000000_string"; 211e41f4b71Sopenharmony_ci/* Perform key agreement. */ 212e41f4b71Sopenharmony_ciOH_Huks_Result HksEcdhAgreeFinish(const struct OH_Huks_Blob *keyAlias, const struct OH_Huks_Blob *publicKey, 213e41f4b71Sopenharmony_ci const struct OH_Huks_ParamSet *initParamSet, const struct OH_Huks_ParamSet *finishParamSet, struct OH_Huks_Blob *outData) 214e41f4b71Sopenharmony_ci{ 215e41f4b71Sopenharmony_ci struct OH_Huks_Blob inData = { 216e41f4b71Sopenharmony_ci (uint32_t)strlen(g_inData), 217e41f4b71Sopenharmony_ci (uint8_t *)g_inData 218e41f4b71Sopenharmony_ci }; 219e41f4b71Sopenharmony_ci uint8_t handleU[sizeof(uint64_t)] = {0}; 220e41f4b71Sopenharmony_ci struct OH_Huks_Blob handle = { sizeof(uint64_t), handleU }; 221e41f4b71Sopenharmony_ci OH_Huks_Result ret = OH_Huks_InitSession(keyAlias, initParamSet, &handle, nullptr); 222e41f4b71Sopenharmony_ci if (ret.errorCode != OH_HUKS_SUCCESS) { 223e41f4b71Sopenharmony_ci return ret; 224e41f4b71Sopenharmony_ci } 225e41f4b71Sopenharmony_ci uint8_t outDataU[ECDH_COMMON_SIZE] = {0}; 226e41f4b71Sopenharmony_ci struct OH_Huks_Blob outDataUpdate = { ECDH_COMMON_SIZE, outDataU }; 227e41f4b71Sopenharmony_ci ret = OH_Huks_UpdateSession(&handle, initParamSet, publicKey, &outDataUpdate); 228e41f4b71Sopenharmony_ci if (ret.errorCode != OH_HUKS_SUCCESS) { 229e41f4b71Sopenharmony_ci return ret; 230e41f4b71Sopenharmony_ci } 231e41f4b71Sopenharmony_ci ret = OH_Huks_FinishSession(&handle, finishParamSet, &inData, outData); 232e41f4b71Sopenharmony_ci if (ret.errorCode != OH_HUKS_SUCCESS) { 233e41f4b71Sopenharmony_ci return ret; 234e41f4b71Sopenharmony_ci } 235e41f4b71Sopenharmony_ci return ret; 236e41f4b71Sopenharmony_ci} 237e41f4b71Sopenharmony_ci/* Key agreement process. */ 238e41f4b71Sopenharmony_cistatic napi_value AgreeKey(napi_env env, napi_callback_info info) 239e41f4b71Sopenharmony_ci{ 240e41f4b71Sopenharmony_ci struct OH_Huks_ParamSet *genParamSet = nullptr; 241e41f4b71Sopenharmony_ci struct OH_Huks_ParamSet *initParamSet01 = nullptr; 242e41f4b71Sopenharmony_ci struct OH_Huks_ParamSet *finishParamSet01 = nullptr; 243e41f4b71Sopenharmony_ci struct OH_Huks_ParamSet *initParamSet02 = nullptr; 244e41f4b71Sopenharmony_ci struct OH_Huks_ParamSet *finishParamSet02 = nullptr; 245e41f4b71Sopenharmony_ci struct OH_Huks_Blob publicKey01 = { .size = OH_HUKS_ECC_KEY_SIZE_256, .data = nullptr }; 246e41f4b71Sopenharmony_ci struct OH_Huks_Blob publicKey02 = { .size = OH_HUKS_ECC_KEY_SIZE_256, .data = nullptr }; 247e41f4b71Sopenharmony_ci struct OH_Huks_Blob outData01 = { .size = ECDH_COMMON_SIZE, .data = nullptr }; 248e41f4b71Sopenharmony_ci struct OH_Huks_Blob outData02 = { .size = ECDH_COMMON_SIZE, .data = nullptr }; 249e41f4b71Sopenharmony_ci OH_Huks_Result ohResult; 250e41f4b71Sopenharmony_ci do { 251e41f4b71Sopenharmony_ci /* 1. Set the key alias and key parameter set. */ 252e41f4b71Sopenharmony_ci ohResult = InitParamSet(&genParamSet, g_genAgreeParams, sizeof(g_genAgreeParams) / sizeof(OH_Huks_Param)); 253e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 254e41f4b71Sopenharmony_ci break; 255e41f4b71Sopenharmony_ci } 256e41f4b71Sopenharmony_ci ohResult = InitParamSet(&initParamSet01, g_agreeParamsInit01, sizeof(g_agreeParamsInit01) / sizeof(OH_Huks_Param)); 257e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 258e41f4b71Sopenharmony_ci break; 259e41f4b71Sopenharmony_ci } 260e41f4b71Sopenharmony_ci ohResult = InitParamSet(&finishParamSet01, g_agreeParamsFinish01, 261e41f4b71Sopenharmony_ci sizeof(g_agreeParamsFinish01) / sizeof(OH_Huks_Param)); 262e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 263e41f4b71Sopenharmony_ci break; 264e41f4b71Sopenharmony_ci } 265e41f4b71Sopenharmony_ci ohResult = InitParamSet(&initParamSet02, g_agreeParamsInit02, sizeof(g_agreeParamsInit02) / sizeof(OH_Huks_Param)); 266e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 267e41f4b71Sopenharmony_ci break; 268e41f4b71Sopenharmony_ci } 269e41f4b71Sopenharmony_ci ohResult = InitParamSet(&finishParamSet02, g_agreeParamsFinish02, 270e41f4b71Sopenharmony_ci sizeof(g_agreeParamsFinish02) / sizeof(OH_Huks_Param)); 271e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 272e41f4b71Sopenharmony_ci break; 273e41f4b71Sopenharmony_ci } 274e41f4b71Sopenharmony_ci /* 2. Generate an asymmetric key pair for device A. */ 275e41f4b71Sopenharmony_ci ohResult = OH_Huks_GenerateKeyItem(&g_keyAlias01001, genParamSet, nullptr); 276e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 277e41f4b71Sopenharmony_ci break; 278e41f4b71Sopenharmony_ci } 279e41f4b71Sopenharmony_ci /* 3. Generate an asymmetric key pair for device B. */ 280e41f4b71Sopenharmony_ci ohResult = OH_Huks_GenerateKeyItem(&g_keyAlias02001, genParamSet, nullptr); 281e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 282e41f4b71Sopenharmony_ci break; 283e41f4b71Sopenharmony_ci } 284e41f4b71Sopenharmony_ci ohResult = MallocAndCheckBlobData(&publicKey01, publicKey01.size); 285e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 286e41f4b71Sopenharmony_ci break; 287e41f4b71Sopenharmony_ci } 288e41f4b71Sopenharmony_ci ohResult = MallocAndCheckBlobData(&publicKey02, publicKey02.size); 289e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 290e41f4b71Sopenharmony_ci break; 291e41f4b71Sopenharmony_ci } 292e41f4b71Sopenharmony_ci /* 4. Export the public key from device A and device B separately. */ 293e41f4b71Sopenharmony_ci ohResult = HksEcdhAgreeExport(&g_keyAlias01001, &g_keyAlias02001, &publicKey01, &publicKey02, genParamSet); 294e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 295e41f4b71Sopenharmony_ci break; 296e41f4b71Sopenharmony_ci } 297e41f4b71Sopenharmony_ci ohResult = MallocAndCheckBlobData(&outData01, outData01.size); 298e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 299e41f4b71Sopenharmony_ci break; 300e41f4b71Sopenharmony_ci } 301e41f4b71Sopenharmony_ci ohResult = MallocAndCheckBlobData(&outData02, outData02.size); 302e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 303e41f4b71Sopenharmony_ci break; 304e41f4b71Sopenharmony_ci } 305e41f4b71Sopenharmony_ci /* 5. Perform key agreement for device A. */ 306e41f4b71Sopenharmony_ci ohResult = HksEcdhAgreeFinish(&g_keyAlias01001, &publicKey02, initParamSet01, finishParamSet01, &outData01); 307e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 308e41f4b71Sopenharmony_ci break; 309e41f4b71Sopenharmony_ci } 310e41f4b71Sopenharmony_ci /* 5. Perform key agreement for device B. */ 311e41f4b71Sopenharmony_ci ohResult = HksEcdhAgreeFinish(&g_keyAlias02001, &publicKey01, initParamSet02, finishParamSet02, &outData02); 312e41f4b71Sopenharmony_ci } while (0); 313e41f4b71Sopenharmony_ci free(publicKey01.data); 314e41f4b71Sopenharmony_ci free(publicKey02.data); 315e41f4b71Sopenharmony_ci free(outData01.data); 316e41f4b71Sopenharmony_ci free(outData02.data); 317e41f4b71Sopenharmony_ci /* 6. Delete keys from device A and device B. */ 318e41f4b71Sopenharmony_ci OH_Huks_DeleteKeyItem(&g_keyAlias01001, genParamSet); 319e41f4b71Sopenharmony_ci OH_Huks_DeleteKeyItem(&g_keyAlias02001, genParamSet); 320e41f4b71Sopenharmony_ci OH_Huks_DeleteKeyItem(&g_keyAliasFinal1001, NULL); 321e41f4b71Sopenharmony_ci OH_Huks_DeleteKeyItem(&g_keyAliasFinal2001, NULL); 322e41f4b71Sopenharmony_ci OH_Huks_FreeParamSet(&genParamSet); 323e41f4b71Sopenharmony_ci OH_Huks_FreeParamSet(&initParamSet01); 324e41f4b71Sopenharmony_ci OH_Huks_FreeParamSet(&finishParamSet01); 325e41f4b71Sopenharmony_ci OH_Huks_FreeParamSet(&initParamSet02); 326e41f4b71Sopenharmony_ci OH_Huks_FreeParamSet(&finishParamSet02); 327e41f4b71Sopenharmony_ci 328e41f4b71Sopenharmony_ci napi_value ret; 329e41f4b71Sopenharmony_ci napi_create_int32(env, ohResult.errorCode, &ret); 330e41f4b71Sopenharmony_ci return ret; 331e41f4b71Sopenharmony_ci} 332e41f4b71Sopenharmony_ci``` 333