• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 // [Start encrypt_import_key]
17 
18 #include "huks/native_huks_api.h"
19 #include "huks/native_huks_param.h"
20 #include "napi/native_api.h"
21 #include <algorithm>
22 
23 #define MAX_MALLOC_SIZE 0x800000
24 
InitParamSet(struct OH_Huks_ParamSet ** paramSet,const struct OH_Huks_Param * params,uint32_t paramCount)25 OH_Huks_Result InitParamSet(struct OH_Huks_ParamSet **paramSet, const struct OH_Huks_Param *params,
26                             uint32_t paramCount)
27 {
28     OH_Huks_Result ret = OH_Huks_InitParamSet(paramSet);
29     if (ret.errorCode != OH_HUKS_SUCCESS) {
30         return ret;
31     }
32     ret = OH_Huks_AddParams(*paramSet, params, paramCount);
33     if (ret.errorCode != OH_HUKS_SUCCESS) {
34         OH_Huks_FreeParamSet(paramSet);
35         return ret;
36     }
37     ret = OH_Huks_BuildParamSet(paramSet);
38     if (ret.errorCode != OH_HUKS_SUCCESS) {
39         OH_Huks_FreeParamSet(paramSet);
40         return ret;
41     }
42     return ret;
43 }
44 struct HksImportWrappedKeyTestParams {
45     // server key, for real.
46     struct OH_Huks_Blob *wrappingKeyAlias;
47     struct OH_Huks_ParamSet *genWrappingKeyParamSet;
48     uint32_t publicKeySize;
49     struct OH_Huks_Blob *callerKeyAlias;
50     struct OH_Huks_ParamSet *genCallerKeyParamSet;
51     struct OH_Huks_Blob *callerKekAlias;
52     struct OH_Huks_Blob *callerKek;
53     struct OH_Huks_ParamSet *importCallerKekParamSet;
54     struct OH_Huks_Blob *callerAgreeKeyAlias;
55     struct OH_Huks_ParamSet *agreeParamSet;
56     struct OH_Huks_ParamSet *importWrappedKeyParamSet;
57     struct OH_Huks_Blob *importedKeyAlias;
58     struct OH_Huks_Blob *importedPlainKey;
59     uint32_t keyMaterialLen;
60 };
61 static const uint32_t IV_SIZE = 16;
62 static uint8_t IV[IV_SIZE] = "bababababababab"; // 此处仅为测试数据,实际使用时该值每次应该不同。
63 static const uint32_t WRAPPED_KEY_IV_SIZE = 16;
64 static uint8_t WRAPPED_KEY_IV[IV_SIZE] = "bababababababab"; // 此处仅为测试数据,实际使用时该值每次应该不同。
65 static const uint32_t AAD_SIZE = 16;
66 static uint8_t AAD[AAD_SIZE] = "abababababababa"; // 此处仅为测试数据,实际使用时该值每次应该不同。
67 static const uint32_t NONCE_SIZE = 12;
68 static uint8_t NONCE[NONCE_SIZE] = "hahahahahah"; // 此处仅为测试数据,实际使用时该值每次应该不同。
69 static const uint32_t AEAD_TAG_SIZE = 16;
70 static const uint32_t X25519_256_SIZE = 256;
71 static struct OH_Huks_Blob g_wrappingKeyAliasAes256 = {.size = (uint32_t)strlen("test_wrappingKey_x25519_aes256"),
72                                                        .data = (uint8_t *)"test_wrappingKey_x25519_aes256"};
73 static struct OH_Huks_Blob g_callerKeyAliasAes256 = {.size = (uint32_t)strlen("test_caller_key_x25519_aes256"),
74                                                      .data = (uint8_t *)"test_caller_key_x25519_aes256"};
75 static struct OH_Huks_Blob g_callerKekAliasAes256 = {.size = (uint32_t)strlen("test_caller_kek_x25519_aes256"),
76                                                      .data = (uint8_t *)"test_caller_kek_x25519_aes256"};
77 static struct OH_Huks_Blob g_callerAes256Kek = {.size = (uint32_t)strlen("This is kek to encrypt plain key"),
78                                                 .data = (uint8_t *)"This is kek to encrypt plain key"};
79 static struct OH_Huks_Blob g_callerAgreeKeyAliasAes256 = {.size =
80                                                               (uint32_t)strlen("test_caller_agree_key_x25519_aes256"),
81                                                           .data = (uint8_t *)"test_caller_agree_key_x25519_aes256"};
82 static struct OH_Huks_Blob g_importedKeyAliasAes256 = {.size = (uint32_t)strlen("test_import_key_x25519_aes256"),
83                                                        .data = (uint8_t *)"test_import_key_x25519_aes256"};
84 static struct OH_Huks_Blob g_importedAes256PlainKey = {.size = (uint32_t)strlen("This is plain key to be imported"),
85                                                        .data = (uint8_t *)"This is plain key to be imported"};
86 static struct OH_Huks_Param g_importWrappedAes256Params[] = {
87     {.tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_AES},
88     {.tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_ENCRYPT | OH_HUKS_KEY_PURPOSE_DECRYPT},
89     {.tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_AES_KEY_SIZE_256},
90     {.tag = OH_HUKS_TAG_PADDING, .uint32Param = OH_HUKS_PADDING_NONE},
91     {.tag = OH_HUKS_TAG_BLOCK_MODE, .uint32Param = OH_HUKS_MODE_GCM},
92     {.tag = OH_HUKS_TAG_DIGEST, .uint32Param = OH_HUKS_DIGEST_NONE},
93     {.tag = OH_HUKS_TAG_UNWRAP_ALGORITHM_SUITE, .uint32Param = OH_HUKS_UNWRAP_SUITE_X25519_AES_256_GCM_NOPADDING},
94     {.tag = OH_HUKS_TAG_ASSOCIATED_DATA,
95      .blob = {.size = AAD_SIZE, .data = (uint8_t *)AAD}}, // 此处仅为测试数据,实际使用时该值应与调用者信息相关。
96     {.tag = OH_HUKS_TAG_NONCE,
97      .blob = {.size = NONCE_SIZE, .data = (uint8_t *)NONCE}}}; // 此处仅为测试数据,实际使用时该值每次应该不同。
98 static const uint32_t g_x25519PubKeySize = 32;
99 static struct OH_Huks_Param g_genWrappingKeyParams[] = {
100     {.tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_X25519},
101     {.tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_UNWRAP},
102     {.tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_CURVE25519_KEY_SIZE_256}};
103 static struct OH_Huks_Param g_genCallerX25519Params[] = {
104     {.tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_X25519},
105     {.tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_AGREE},
106     {.tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_CURVE25519_KEY_SIZE_256}};
107 static struct OH_Huks_Param g_importParamsCallerKek[] = {
108     {.tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_AES},
109     {.tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_ENCRYPT},
110     {.tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_AES_KEY_SIZE_256},
111     {.tag = OH_HUKS_TAG_PADDING, .uint32Param = OH_HUKS_PADDING_NONE},
112     {.tag = OH_HUKS_TAG_BLOCK_MODE, .uint32Param = OH_HUKS_MODE_GCM},
113     {.tag = OH_HUKS_TAG_DIGEST, .uint32Param = OH_HUKS_DIGEST_NONE},
114     {.tag = OH_HUKS_TAG_IV,
115      .blob = {.size = WRAPPED_KEY_IV_SIZE,
116               .data = (uint8_t *)WRAPPED_KEY_IV}}}; // 此处仅为测试数据,实际使用时该值每次应该不同。
117 static struct OH_Huks_Param g_callerAgreeParams[] = {
118     {.tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_X25519},
119     {.tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_AGREE},
120     {.tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_CURVE25519_KEY_SIZE_256}};
121 static struct OH_Huks_Param g_aesKekEncryptParams[] = {
122     {.tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_AES},
123     {.tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_ENCRYPT},
124     {.tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_AES_KEY_SIZE_256},
125     {.tag = OH_HUKS_TAG_PADDING, .uint32Param = OH_HUKS_PADDING_NONE},
126     {.tag = OH_HUKS_TAG_BLOCK_MODE, .uint32Param = OH_HUKS_MODE_GCM},
127     {.tag = OH_HUKS_TAG_DIGEST, .uint32Param = OH_HUKS_DIGEST_NONE},
128     {.tag = OH_HUKS_TAG_ASSOCIATED_DATA,
129      .blob = {.size = AAD_SIZE, .data = (uint8_t *)AAD}}, // 此处仅为测试数据,实际使用时该值应与调用者信息相关。
130     {.tag = OH_HUKS_TAG_NONCE,
131      .blob = {.size = NONCE_SIZE, .data = (uint8_t *)NONCE}}}; // 此处仅为测试数据,实际使用时该值每次应该不同。
132 static struct OH_Huks_Param g_importAgreeKeyParams[] = {
133     {.tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_AES},
134     {.tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_ENCRYPT},
135     {.tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_AES_KEY_SIZE_256},
136     {.tag = OH_HUKS_TAG_PADDING, .uint32Param = OH_HUKS_PADDING_NONE},
137     {.tag = OH_HUKS_TAG_BLOCK_MODE, .uint32Param = OH_HUKS_MODE_GCM},
138     {.tag = OH_HUKS_TAG_DIGEST, .uint32Param = OH_HUKS_DIGEST_NONE},
139     {.tag = OH_HUKS_TAG_IV,
140      .blob = {.size = IV_SIZE, .data = (uint8_t *)IV}}}; // 此处仅为测试数据,实际使用时该值每次应该不同。
HuksAgreeKey(const struct OH_Huks_ParamSet * paramSet,const struct OH_Huks_Blob * keyAlias,const struct OH_Huks_Blob * peerPublicKey,struct OH_Huks_Blob * agreedKey)141 OH_Huks_Result HuksAgreeKey(const struct OH_Huks_ParamSet *paramSet, const struct OH_Huks_Blob *keyAlias,
142                             const struct OH_Huks_Blob *peerPublicKey, struct OH_Huks_Blob *agreedKey)
143 {
144     uint8_t temp[10] = {0};
145     struct OH_Huks_Blob inData = {sizeof(temp), temp};
146     uint8_t handleU[sizeof(uint64_t)] = {0};
147     struct OH_Huks_Blob handle = {sizeof(uint64_t), handleU};
148     OH_Huks_Result ret = OH_Huks_InitSession(keyAlias, paramSet, &handle, nullptr);
149     if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
150         return ret;
151     }
152     uint8_t outDataU[1024] = {0};
153     struct OH_Huks_Blob outDataUpdate = {1024, outDataU};
154     ret = OH_Huks_UpdateSession(&handle, paramSet, peerPublicKey, &outDataUpdate);
155     if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
156         return ret;
157     }
158     ret = OH_Huks_FinishSession(&handle, paramSet, &inData, agreedKey);
159     if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
160         return ret;
161     }
162     return ret;
163 }
MallocAndCheckBlobData(struct OH_Huks_Blob * blob,const uint32_t blobSize)164 OH_Huks_Result MallocAndCheckBlobData(struct OH_Huks_Blob *blob, const uint32_t blobSize)
165 {
166     struct OH_Huks_Result ret;
167     ret.errorCode = OH_HUKS_SUCCESS;
168     if (blobSize == 0 || blobSize > MAX_MALLOC_SIZE) {
169         ret.errorCode = OH_HUKS_ERR_CODE_INTERNAL_ERROR;
170     }
171     blob->data = (uint8_t *)malloc(blobSize);
172     if (blob->data == NULL) {
173         ret.errorCode = OH_HUKS_ERR_CODE_INTERNAL_ERROR;
174     }
175     return ret;
176 }
177 static const uint32_t TIMES = 4;
178 static const uint32_t MAX_UPDATE_SIZE = 64;
179 static const uint32_t MAX_OUTDATA_SIZE = MAX_UPDATE_SIZE * TIMES;
180 #define HUKS_FREE_BLOB(blob)                                                                                           \
181     do {                                                                                                               \
182         if ((blob).data != nullptr) {                                                                                  \
183             free((blob).data);                                                                                         \
184             (blob).data = nullptr;                                                                                     \
185         }                                                                                                              \
186         (blob).size = 0;                                                                                               \
187     } while (0)
188 #define OH_HUKS_KEY_BYTES(keySize) (((keySize) + 7) / 8)
HksEncryptLoopUpdate(const struct OH_Huks_Blob * handle,const struct OH_Huks_ParamSet * paramSet,const struct OH_Huks_Blob * inData,struct OH_Huks_Blob * outData)189 static OH_Huks_Result HksEncryptLoopUpdate(const struct OH_Huks_Blob *handle, const struct OH_Huks_ParamSet *paramSet,
190                                            const struct OH_Huks_Blob *inData, struct OH_Huks_Blob *outData)
191 {
192     struct OH_Huks_Result ret;
193     ret.errorCode = OH_HUKS_SUCCESS;
194     struct OH_Huks_Blob inDataSeg = *inData;
195     uint8_t *lastPtr = inData->data + inData->size - 1;
196     struct OH_Huks_Blob outDataSeg = {MAX_OUTDATA_SIZE, NULL};
197     uint8_t *cur = outData->data;
198     outData->size = 0;
199     inDataSeg.size = MAX_UPDATE_SIZE;
200     bool isFinished = false;
201     while (inDataSeg.data <= lastPtr) {
202         if (inDataSeg.data + MAX_UPDATE_SIZE <= lastPtr) {
203             outDataSeg.size = MAX_OUTDATA_SIZE;
204         } else {
205             isFinished = true;
206             inDataSeg.size = lastPtr - inDataSeg.data + 1;
207             break;
208         }
209         if (MallocAndCheckBlobData(&outDataSeg, outDataSeg.size).errorCode != (int32_t)OH_HUKS_SUCCESS) {
210             ret.errorCode = OH_HUKS_ERR_CODE_INTERNAL_ERROR;
211             return ret;
212         }
213         ret = OH_Huks_UpdateSession(handle, paramSet, &inDataSeg, &outDataSeg);
214         if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
215             free(outDataSeg.data);
216             return ret;
217         }
218         std::copy(outDataSeg.data, outDataSeg.data + outDataSeg.size, cur);
219         cur += outDataSeg.size;
220         outData->size += outDataSeg.size;
221         free(outDataSeg.data);
222         if ((isFinished == false) && (inDataSeg.data + MAX_UPDATE_SIZE > lastPtr)) {
223             ret.errorCode = OH_HUKS_ERR_CODE_INTERNAL_ERROR;
224             return ret;
225         }
226         inDataSeg.data += MAX_UPDATE_SIZE;
227     }
228     struct OH_Huks_Blob outDataFinish = {inDataSeg.size * TIMES, NULL};
229     if (MallocAndCheckBlobData(&outDataFinish, outDataFinish.size).errorCode != (int32_t)OH_HUKS_SUCCESS) {
230         ret.errorCode = OH_HUKS_ERR_CODE_INTERNAL_ERROR;
231         return ret;
232     }
233     ret = OH_Huks_FinishSession(handle, paramSet, &inDataSeg, &outDataFinish);
234     if (ret.errorCode != OH_HUKS_SUCCESS) {
235         free(outDataFinish.data);
236         return ret;
237     }
238     std::copy(outDataFinish.data, outDataFinish.data + outDataFinish.size, cur);
239     outData->size += outDataFinish.size;
240     free(outDataFinish.data);
241     return ret;
242 }
HuksEncrypt(const struct OH_Huks_Blob * key,const struct OH_Huks_ParamSet * paramSet,const struct OH_Huks_Blob * plainText,struct OH_Huks_Blob * cipherText)243 OH_Huks_Result HuksEncrypt(const struct OH_Huks_Blob *key, const struct OH_Huks_ParamSet *paramSet,
244                            const struct OH_Huks_Blob *plainText, struct OH_Huks_Blob *cipherText)
245 {
246     uint8_t handle[sizeof(uint64_t)] = {0};
247     struct OH_Huks_Blob handleBlob = {sizeof(uint64_t), handle};
248     OH_Huks_Result ret = OH_Huks_InitSession(key, paramSet, &handleBlob, nullptr);
249     if (ret.errorCode != OH_HUKS_SUCCESS) {
250         return ret;
251     }
252     ret = HksEncryptLoopUpdate(&handleBlob, paramSet, plainText, cipherText);
253     return ret;
254 }
BuildWrappedKeyData(struct OH_Huks_Blob ** blobArray,uint32_t size,struct OH_Huks_Blob * outData)255 static OH_Huks_Result BuildWrappedKeyData(struct OH_Huks_Blob **blobArray, uint32_t size,
256                                           struct OH_Huks_Blob *outData)
257 {
258     uint32_t totalLength = size * sizeof(uint32_t);
259     struct OH_Huks_Result ret;
260     ret.errorCode = OH_HUKS_SUCCESS;
261     /* 计算大小 */
262     for (uint32_t i = 0; i < size; ++i) {
263         totalLength += blobArray[i]->size;
264     }
265     struct OH_Huks_Blob outBlob = {0, nullptr};
266     outBlob.size = totalLength;
267     ret = MallocAndCheckBlobData(&outBlob, outBlob.size);
268     if (ret.errorCode != OH_HUKS_SUCCESS) {
269         return ret;
270     }
271     uint32_t offset = 0;
272     /* 拷贝数据 */
273     for (uint32_t i = 0; i < size; ++i) {
274         if (totalLength - offset >= sizeof(blobArray[i]->size)) {
275             std::copy(reinterpret_cast<uint8_t *>(&blobArray[i]->size),
276                       reinterpret_cast<uint8_t *>(&blobArray[i]->size) + sizeof(blobArray[i]->size),
277                       outBlob.data + offset);
278         } else {
279             ret.errorCode = OH_HUKS_ERR_CODE_INTERNAL_ERROR;
280             return ret;
281         }
282         offset += sizeof(blobArray[i]->size);
283         if (totalLength - offset >= blobArray[i]->size) {
284             std::copy(blobArray[i]->data, blobArray[i]->data + blobArray[i]->size, outBlob.data + offset);
285         } else {
286             ret.errorCode = OH_HUKS_ERR_CODE_INTERNAL_ERROR;
287             return ret;
288         }
289         offset += blobArray[i]->size;
290     }
291     outData->size = outBlob.size;
292     outData->data = outBlob.data;
293     return ret;
294 }
CheckParamsValid(const struct HksImportWrappedKeyTestParams * params)295 static OH_Huks_Result CheckParamsValid(const struct HksImportWrappedKeyTestParams *params)
296 {
297     struct OH_Huks_Result ret;
298     ret.errorCode = OH_HUKS_SUCCESS;
299     if (params == nullptr) {
300         ret.errorCode = OH_HUKS_ERR_CODE_ILLEGAL_ARGUMENT;
301         return ret;
302     }
303     if (params->wrappingKeyAlias == nullptr || params->genWrappingKeyParamSet == nullptr ||
304         params->callerKeyAlias == nullptr || params->genCallerKeyParamSet == nullptr ||
305         params->callerKekAlias == nullptr || params->callerKek == nullptr ||
306         params->importCallerKekParamSet == nullptr || params->callerAgreeKeyAlias == nullptr ||
307         params->agreeParamSet == nullptr || params->importWrappedKeyParamSet == nullptr ||
308         params->importedKeyAlias == nullptr || params->importedPlainKey == nullptr) {
309         ret.errorCode = OH_HUKS_ERR_CODE_ILLEGAL_ARGUMENT;
310         return ret;
311     }
312     return ret;
313 }
GenerateAndExportHuksPublicKey(const struct HksImportWrappedKeyTestParams * params,struct OH_Huks_Blob * huksPublicKey)314 static OH_Huks_Result GenerateAndExportHuksPublicKey(const struct HksImportWrappedKeyTestParams *params,
315                                                      struct OH_Huks_Blob *huksPublicKey)
316 {
317     OH_Huks_Result ret = OH_Huks_GenerateKeyItem(params->wrappingKeyAlias, params->genWrappingKeyParamSet, nullptr);
318     if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
319         return ret;
320     }
321     huksPublicKey->size = params->publicKeySize;
322     ret = MallocAndCheckBlobData(huksPublicKey, huksPublicKey->size);
323     if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
324         return ret;
325     }
326     ret = OH_Huks_ExportPublicKeyItem(params->wrappingKeyAlias, nullptr, huksPublicKey);
327     return ret;
328 }
GenerateAndExportCallerPublicKey(const struct HksImportWrappedKeyTestParams * params,struct OH_Huks_Blob * callerSelfPublicKey)329 static OH_Huks_Result GenerateAndExportCallerPublicKey(const struct HksImportWrappedKeyTestParams *params,
330                                                        struct OH_Huks_Blob *callerSelfPublicKey)
331 {
332     OH_Huks_Result ret = OH_Huks_GenerateKeyItem(params->callerKeyAlias, params->genCallerKeyParamSet, nullptr);
333     if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
334         return ret;
335     }
336     callerSelfPublicKey->size = params->publicKeySize;
337     ret = MallocAndCheckBlobData(callerSelfPublicKey, callerSelfPublicKey->size);
338     if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
339         return ret;
340     }
341     ret = OH_Huks_ExportPublicKeyItem(params->callerKeyAlias, params->genWrappingKeyParamSet, callerSelfPublicKey);
342     return ret;
343 }
ImportKekAndAgreeSharedSecret(const struct HksImportWrappedKeyTestParams * params,const struct OH_Huks_Blob * huksPublicKey,struct OH_Huks_Blob * outSharedKey)344 static OH_Huks_Result ImportKekAndAgreeSharedSecret(const struct HksImportWrappedKeyTestParams *params,
345                                                     const struct OH_Huks_Blob *huksPublicKey,
346                                                     struct OH_Huks_Blob *outSharedKey)
347 {
348     OH_Huks_Result ret =
349         OH_Huks_ImportKeyItem(params->callerKekAlias, params->importCallerKekParamSet, params->callerKek);
350     if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
351         return ret;
352     }
353     ret = MallocAndCheckBlobData(outSharedKey, outSharedKey->size);
354     if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
355         return ret;
356     }
357     ret = HuksAgreeKey(params->agreeParamSet, params->callerKeyAlias, huksPublicKey, outSharedKey);
358     if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
359         return ret;
360     }
361     struct OH_Huks_ParamSet *importAgreeKeyParams = nullptr;
362     ret = InitParamSet(&importAgreeKeyParams, g_importAgreeKeyParams,
363                        sizeof(g_importAgreeKeyParams) / sizeof(OH_Huks_Param));
364     if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
365         return ret;
366     }
367     ret = OH_Huks_ImportKeyItem(params->callerAgreeKeyAlias, importAgreeKeyParams, outSharedKey);
368     OH_Huks_FreeParamSet(&importAgreeKeyParams);
369     return ret;
370 }
EncryptImportedPlainKeyAndKek(const struct HksImportWrappedKeyTestParams * params,struct OH_Huks_Blob * plainCipherText,struct OH_Huks_Blob * kekCipherText)371 static OH_Huks_Result EncryptImportedPlainKeyAndKek(const struct HksImportWrappedKeyTestParams *params,
372                                                     struct OH_Huks_Blob *plainCipherText,
373                                                     struct OH_Huks_Blob *kekCipherText)
374 {
375     struct OH_Huks_ParamSet *encryptParamSet = nullptr;
376     OH_Huks_Result ret =
377         InitParamSet(&encryptParamSet, g_aesKekEncryptParams, sizeof(g_aesKekEncryptParams) / sizeof(OH_Huks_Param));
378     if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
379         return ret;
380     }
381     ret = HuksEncrypt(params->callerKekAlias, encryptParamSet, params->importedPlainKey, plainCipherText);
382     if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
383         return ret;
384     }
385     ret = HuksEncrypt(params->callerAgreeKeyAlias, encryptParamSet, params->callerKek, kekCipherText);
386     OH_Huks_FreeParamSet(&encryptParamSet);
387     return ret;
388 }
ImportWrappedKey(const struct HksImportWrappedKeyTestParams * params,struct OH_Huks_Blob * plainCipher,struct OH_Huks_Blob * kekCipherText,struct OH_Huks_Blob * peerPublicKey,struct OH_Huks_Blob * wrappedKeyData)389 static OH_Huks_Result ImportWrappedKey(const struct HksImportWrappedKeyTestParams *params,
390                                        struct OH_Huks_Blob *plainCipher, struct OH_Huks_Blob *kekCipherText,
391                                        struct OH_Huks_Blob *peerPublicKey, struct OH_Huks_Blob *wrappedKeyData)
392 {
393     struct OH_Huks_Blob commonAad = {.size = AAD_SIZE, .data = reinterpret_cast<uint8_t *>(AAD)};
394     struct OH_Huks_Blob commonNonce = {.size = NONCE_SIZE, .data = reinterpret_cast<uint8_t *>(NONCE)};
395     struct OH_Huks_Blob keyMaterialLen = {.size = sizeof(uint32_t), .data = (uint8_t *)&params->keyMaterialLen};
396     /* 从密文中拷贝AEAD的tag并缩小其大小 */
397     const uint32_t tagSize = AEAD_TAG_SIZE;
398     uint8_t kekTagBuf[tagSize] = {0};
399     struct OH_Huks_Blob kekTag = {.size = tagSize, .data = kekTagBuf};
400     std::copy(plainCipher->data + (plainCipher->size - tagSize),
401               plainCipher->data + (plainCipher->size - tagSize) + tagSize, kekTag.data);
402     plainCipher->size -= tagSize;
403     /* 从密钥加密密钥的密文中拷贝AEAD的tag并缩小其大小 */
404     uint8_t agreeKeyTagBuf[tagSize] = {0};
405     struct OH_Huks_Blob agreeKeyTag = {.size = tagSize, .data = agreeKeyTagBuf};
406     std::copy(kekCipherText->data + (kekCipherText->size - tagSize),
407               kekCipherText->data + (kekCipherText->size - tagSize) + tagSize, agreeKeyTagBuf);
408     kekCipherText->size -= tagSize;
409     struct OH_Huks_Blob *blobArray[] = {peerPublicKey, &commonAad,   &commonNonce, &agreeKeyTag,    kekCipherText,
410                                         &commonAad,    &commonNonce, &kekTag,      &keyMaterialLen, plainCipher};
411     OH_Huks_Result ret = BuildWrappedKeyData(blobArray, OH_HUKS_IMPORT_WRAPPED_KEY_TOTAL_BLOBS, wrappedKeyData);
412     if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
413         return ret;
414     }
415     struct OH_Huks_Param *purpose = nullptr;
416     ret = OH_Huks_GetParam(params->importWrappedKeyParamSet, OH_HUKS_TAG_PURPOSE, &purpose);
417     if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
418         return ret;
419     }
420     ret = OH_Huks_ImportWrappedKeyItem(params->importedKeyAlias, params->wrappingKeyAlias,
421                                        params->importWrappedKeyParamSet, wrappedKeyData);
422     return ret;
423 }
HksImportWrappedKeyTestCommonCase(const struct HksImportWrappedKeyTestParams * params)424 OH_Huks_Result HksImportWrappedKeyTestCommonCase(const struct HksImportWrappedKeyTestParams *params)
425 {
426     OH_Huks_Result ret = CheckParamsValid(params);
427     if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
428         return ret;
429     }
430     struct OH_Huks_Blob huksPublicKey = {0, nullptr};
431     struct OH_Huks_Blob callerSelfPublicKey = {0, nullptr};
432     struct OH_Huks_Blob outSharedKey = {.size = OH_HUKS_KEY_BYTES(OH_HUKS_AES_KEY_SIZE_256), .data = nullptr};
433     struct OH_Huks_Blob wrappedKeyData = {0, nullptr};
434     uint8_t plainKeyCipherBuffer[OH_HUKS_MAX_KEY_SIZE] = {0};
435     struct OH_Huks_Blob plainCipherText = {OH_HUKS_MAX_KEY_SIZE, plainKeyCipherBuffer};
436     uint8_t kekCipherTextBuffer[OH_HUKS_MAX_KEY_SIZE] = {0};
437     struct OH_Huks_Blob kekCipherText = {OH_HUKS_MAX_KEY_SIZE, kekCipherTextBuffer};
438     /* 模拟加密导入密钥场景,设备A为远端设备(导入设备),设备B为本端设备(被导入设备) */
439     do {
440         /**
441          * 1.设备A将待导入密钥转换成HUKS密钥材料格式To_Import_Key(仅针对非对称密钥,若待导入密钥是对称密钥则可省略此步骤),
442          *   本示例使用g_importedAes256PlainKey(对称密钥)作为模拟
443          */
444         /* 2.设备B生成一个加密导入用途的、用于协商的非对称密钥对Wrapping_Key(公钥Wrapping_Pk,私钥Wrapping_Sk),
445          * 其密钥用途设置为unwrap,导出Wrapping_Key公钥Wrapping_Pk存放在变量huksPublicKey中
446          */
447         ret = GenerateAndExportHuksPublicKey(params, &huksPublicKey);
448         if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
449             break;
450         }
451         /* 3.设备A使用和设备B同样的算法,生成一个加密导入用途的、用于协商的非对称密钥对Caller_Key(公钥Caller_Pk,私钥Caller_Sk),
452          * 导出Caller_Key公钥Caller_Pk存放在变量callerSelfPublicKey中
453          */
454         ret = GenerateAndExportCallerPublicKey(params, &callerSelfPublicKey);
455         if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
456             break;
457         }
458         /**
459          * 4. 设备A生成一个对称密钥Caller_Kek,该密钥后续将用于加密To_Import_Key
460          * 5. 设备A基于Caller_Key的私钥Caller_Sk和设备B Wrapping_Key的公钥Wrapping_Pk,协商出Shared_Key
461          */
462         ret = ImportKekAndAgreeSharedSecret(params, &huksPublicKey, &outSharedKey);
463         if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
464             break;
465         }
466         /**
467          * 6. 设备A使用Caller_Kek加密To_Import_Key,生成To_Import_Key_Enc
468          * 7. 设备A使用Shared_Key加密Caller_Kek,生成Caller_Kek_Enc
469          */
470         ret = EncryptImportedPlainKeyAndKek(params, &plainCipherText, &kekCipherText);
471         if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
472             break;
473         }
474         /* 8. 设备A封装Caller_Pk、To_Import_Key_Enc、Caller_Kek_Enc等加密导入的材料并发送给设备B。
475          * 本示例作为变量存放在callerSelfPublicKey,plainCipherText,kekCipherText
476          * 9. 设备B导入封装的加密密钥材料
477          */
478         ret = ImportWrappedKey(params, &plainCipherText, &kekCipherText, &callerSelfPublicKey, &wrappedKeyData);
479     } while (0);
480     /* 10. 设备A、B删除用于加密导入的密钥 */
481     HUKS_FREE_BLOB(huksPublicKey);
482     HUKS_FREE_BLOB(callerSelfPublicKey);
483     HUKS_FREE_BLOB(outSharedKey);
484     HUKS_FREE_BLOB(wrappedKeyData);
485     return ret;
486 }
HksClearKeysForWrappedKeyTest(const struct HksImportWrappedKeyTestParams * params)487 void HksClearKeysForWrappedKeyTest(const struct HksImportWrappedKeyTestParams *params)
488 {
489     OH_Huks_Result ret = CheckParamsValid(params);
490     if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
491         return;
492     }
493     (void)OH_Huks_DeleteKeyItem(params->wrappingKeyAlias, nullptr);
494     (void)OH_Huks_DeleteKeyItem(params->callerKeyAlias, nullptr);
495     (void)OH_Huks_DeleteKeyItem(params->callerKekAlias, nullptr);
496     (void)OH_Huks_DeleteKeyItem(params->callerAgreeKeyAlias, nullptr);
497     (void)OH_Huks_DeleteKeyItem(params->importedKeyAlias, nullptr);
498 }
InitCommonTestParamsAndDoImport(struct HksImportWrappedKeyTestParams * importWrappedKeyTestParams,const struct OH_Huks_Param * importedKeyParamSetArray,uint32_t arraySize)499 static OH_Huks_Result InitCommonTestParamsAndDoImport(struct HksImportWrappedKeyTestParams *importWrappedKeyTestParams,
500                                                       const struct OH_Huks_Param *importedKeyParamSetArray,
501                                                       uint32_t arraySize)
502 {
503     struct OH_Huks_ParamSet *genX25519KeyParamSet = nullptr;
504     struct OH_Huks_ParamSet *genCallerKeyParamSet = nullptr;
505     struct OH_Huks_ParamSet *callerImportParamsKek = nullptr;
506     struct OH_Huks_ParamSet *agreeParamSet = nullptr;
507     struct OH_Huks_ParamSet *importPlainKeyParams = nullptr;
508     OH_Huks_Result ret;
509     do {
510         ret = InitParamSet(&genX25519KeyParamSet, g_genWrappingKeyParams,
511                            sizeof(g_genWrappingKeyParams) / sizeof(OH_Huks_Param));
512         if (ret.errorCode != OH_HUKS_SUCCESS) {
513             break;
514         }
515         importWrappedKeyTestParams->genWrappingKeyParamSet = genX25519KeyParamSet;
516         importWrappedKeyTestParams->publicKeySize = g_x25519PubKeySize;
517         ret = InitParamSet(&genCallerKeyParamSet, g_genCallerX25519Params,
518                            sizeof(g_genCallerX25519Params) / sizeof(OH_Huks_Param));
519         if (ret.errorCode != OH_HUKS_SUCCESS) {
520             break;
521         }
522         importWrappedKeyTestParams->genCallerKeyParamSet = genCallerKeyParamSet;
523         ret = InitParamSet(&callerImportParamsKek, g_importParamsCallerKek,
524                            sizeof(g_importParamsCallerKek) / sizeof(OH_Huks_Param));
525         if (ret.errorCode != OH_HUKS_SUCCESS) {
526             break;
527         }
528         importWrappedKeyTestParams->importCallerKekParamSet = callerImportParamsKek;
529         ret = InitParamSet(&agreeParamSet, g_callerAgreeParams, sizeof(g_callerAgreeParams) / sizeof(OH_Huks_Param));
530         if (ret.errorCode != OH_HUKS_SUCCESS) {
531             break;
532         }
533         importWrappedKeyTestParams->agreeParamSet = agreeParamSet;
534         ret = InitParamSet(&importPlainKeyParams, importedKeyParamSetArray, arraySize);
535         if (ret.errorCode != OH_HUKS_SUCCESS) {
536             break;
537         }
538         importWrappedKeyTestParams->importWrappedKeyParamSet = importPlainKeyParams;
539         ret = HksImportWrappedKeyTestCommonCase(importWrappedKeyTestParams);
540     } while (0);
541     OH_Huks_FreeParamSet(&genX25519KeyParamSet);
542     OH_Huks_FreeParamSet(&genCallerKeyParamSet);
543     OH_Huks_FreeParamSet(&callerImportParamsKek);
544     OH_Huks_FreeParamSet(&agreeParamSet);
545     OH_Huks_FreeParamSet(&importPlainKeyParams);
546     return ret;
547 }
NAPI_Global_importWrappedKey(napi_env env,napi_callback_info info)548 static napi_value NAPI_Global_importWrappedKey(napi_env env, napi_callback_info info)
549 {
550     struct HksImportWrappedKeyTestParams importWrappedKeyTestParams001 = {0};
551     importWrappedKeyTestParams001.wrappingKeyAlias = &g_wrappingKeyAliasAes256;
552     importWrappedKeyTestParams001.keyMaterialLen = g_importedAes256PlainKey.size;
553     importWrappedKeyTestParams001.callerKeyAlias = &g_callerKeyAliasAes256;
554     importWrappedKeyTestParams001.callerKekAlias = &g_callerKekAliasAes256;
555     importWrappedKeyTestParams001.callerKek = &g_callerAes256Kek;
556     importWrappedKeyTestParams001.callerAgreeKeyAlias = &g_callerAgreeKeyAliasAes256;
557     importWrappedKeyTestParams001.importedKeyAlias = &g_importedKeyAliasAes256;
558     importWrappedKeyTestParams001.importedPlainKey = &g_importedAes256PlainKey;
559     OH_Huks_Result ohResult =
560         InitCommonTestParamsAndDoImport(&importWrappedKeyTestParams001, g_importWrappedAes256Params,
561                                         sizeof(g_importWrappedAes256Params) / sizeof(struct OH_Huks_Param));
562     HksClearKeysForWrappedKeyTest(&importWrappedKeyTestParams001);
563     napi_value ret;
564     napi_create_int32(env, ohResult.errorCode, &ret);
565     return ret;
566 }
567 
568 
569 // [End encrypt_import_key]
570 
571 
572 // [Start encryption_import_key_commissioning_and_verification]
IsKeyExist(napi_env env,napi_callback_info info)573 static napi_value IsKeyExist(napi_env env, napi_callback_info info)
574 {
575     /* 1.指定密钥别名 */
576     struct OH_Huks_Blob keyAlias = {
577         (uint32_t)strlen("test_key"),
578         (uint8_t *)"test_key"
579     };
580 
581     /* 2.调用OH_Huks_IsKeyItemExist判断密钥是否存在  */
582     struct OH_Huks_Result ohResult = OH_Huks_IsKeyItemExist(&keyAlias, NULL);
583     napi_value ret;
584     napi_create_int32(env, ohResult.errorCode, &ret);
585     return ret;
586 }
587 
588 // [End encryption_import_key_commissioning_and_verification]
589 
590 EXTERN_C_START
Init(napi_env env,napi_value exports)591 static napi_value Init(napi_env env, napi_value exports)
592 {
593     napi_property_descriptor desc[] = {
594         {"isKeyExist", nullptr, IsKeyExist, nullptr, nullptr, nullptr, napi_default, nullptr },
595         {"importWrappedKey", nullptr, NAPI_Global_importWrappedKey, nullptr, nullptr, nullptr, napi_default, nullptr }};
596     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
597     return exports;
598 }
599 EXTERN_C_END
600 
601 static napi_module demoModule = {
602     .nm_version = 1,
603     .nm_flags = 0,
604     .nm_filename = nullptr,
605     .nm_register_func = Init,
606     .nm_modname = "entry",
607     .nm_priv = ((void *)0),
608     .reserved = {0},
609 };
610 
RegisterEntryModule(void)611 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
612