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 *)¶ms->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