• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022-2024 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 #include "napi_utils.h"
17 #include "params_parser.h"
18 #include "log.h"
19 #include "memory.h"
20 #include "securec.h"
21 #include "napi_crypto_framework_defines.h"
22 #include "detailed_iv_params.h"
23 #include "detailed_gcm_params.h"
24 #include "detailed_ccm_params.h"
25 #include "detailed_dsa_key_params.h"
26 #include "detailed_ecc_key_params.h"
27 #include "detailed_rsa_key_params.h"
28 #include "detailed_alg_25519_key_params.h"
29 #include "detailed_dh_key_params.h"
30 #include "utils.h"
31 #include "pri_key.h"
32 #include "asy_key_generator.h"
33 
34 namespace OHOS {
35 namespace CryptoFramework {
36 using namespace std;
37 
38 constexpr int PASSWORD_MAX_LENGTH = 4096;
39 struct AsyKeySpecItemRelationT {
40     AsyKeySpecItem item;
41     int32_t itemType;
42 };
43 using AsyKeySpecItemRelation = AsyKeySpecItemRelationT;
44 
45 static const AsyKeySpecItemRelation ASY_KEY_SPEC_RELATION_SET[] = {
46     { DSA_P_BN, SPEC_ITEM_TYPE_BIG_INT },
47     { DSA_Q_BN, SPEC_ITEM_TYPE_BIG_INT },
48     { DSA_G_BN, SPEC_ITEM_TYPE_BIG_INT },
49     { DSA_SK_BN, SPEC_ITEM_TYPE_BIG_INT },
50     { DSA_PK_BN, SPEC_ITEM_TYPE_BIG_INT },
51 
52     { ECC_FP_P_BN, SPEC_ITEM_TYPE_BIG_INT },
53     { ECC_A_BN, SPEC_ITEM_TYPE_BIG_INT },
54     { ECC_B_BN, SPEC_ITEM_TYPE_BIG_INT },
55     { ECC_G_X_BN, SPEC_ITEM_TYPE_BIG_INT },
56     { ECC_G_Y_BN, SPEC_ITEM_TYPE_BIG_INT },
57     { ECC_N_BN, SPEC_ITEM_TYPE_BIG_INT },
58     { ECC_H_INT, SPEC_ITEM_TYPE_NUM },  // warning: ECC_H_NUM in JS
59     { ECC_SK_BN, SPEC_ITEM_TYPE_BIG_INT },
60     { ECC_PK_X_BN, SPEC_ITEM_TYPE_BIG_INT },
61     { ECC_PK_Y_BN, SPEC_ITEM_TYPE_BIG_INT },
62     { ECC_FIELD_TYPE_STR, SPEC_ITEM_TYPE_STR },
63     { ECC_FIELD_SIZE_INT, SPEC_ITEM_TYPE_NUM },  // warning: ECC_FIELD_SIZE_NUM in JS
64     { ECC_CURVE_NAME_STR, SPEC_ITEM_TYPE_STR },
65 
66     { RSA_N_BN, SPEC_ITEM_TYPE_BIG_INT },
67     { RSA_SK_BN, SPEC_ITEM_TYPE_BIG_INT },
68     { RSA_PK_BN, SPEC_ITEM_TYPE_BIG_INT },
69     { DH_P_BN, SPEC_ITEM_TYPE_BIG_INT },
70     { DH_G_BN, SPEC_ITEM_TYPE_BIG_INT },
71     { DH_L_NUM, SPEC_ITEM_TYPE_NUM },
72     { DH_PK_BN, SPEC_ITEM_TYPE_BIG_INT },
73     { DH_SK_BN, SPEC_ITEM_TYPE_BIG_INT },
74     { ED25519_SK_BN, SPEC_ITEM_TYPE_BIG_INT },
75     { ED25519_PK_BN, SPEC_ITEM_TYPE_BIG_INT },
76     { X25519_SK_BN, SPEC_ITEM_TYPE_BIG_INT },
77     { X25519_PK_BN, SPEC_ITEM_TYPE_BIG_INT },
78 };
79 
GetAsyKeySpecType(AsyKeySpecItem targetItemType)80 int32_t GetAsyKeySpecType(AsyKeySpecItem targetItemType)
81 {
82     for (uint32_t i = 0; i < sizeof(ASY_KEY_SPEC_RELATION_SET) / sizeof(AsyKeySpecItemRelation); i++) {
83         if (ASY_KEY_SPEC_RELATION_SET[i].item == targetItemType) {
84             return ASY_KEY_SPEC_RELATION_SET[i].itemType;
85         }
86     }
87     LOGE("AsyKeySpecItem not support! ItemType: %d", targetItemType);
88     return -1;
89 }
90 
GetSignSpecType(SignSpecItem targetItemType)91 int32_t GetSignSpecType(SignSpecItem targetItemType)
92 {
93     if (targetItemType == PSS_MD_NAME_STR || targetItemType == PSS_MGF_NAME_STR ||
94         targetItemType == PSS_MGF1_MD_STR) {
95         return SPEC_ITEM_TYPE_STR;
96     }
97     if (targetItemType == SM2_USER_ID_UINT8ARR) {
98         return SPEC_ITEM_TYPE_UINT8ARR;
99     }
100     if (targetItemType == PSS_SALT_LEN_INT || targetItemType == PSS_TRAILER_FIELD_INT) {
101         return SPEC_ITEM_TYPE_NUM;
102     }
103     LOGE("SignSpecItem not support! ItemType: %d", targetItemType);
104     return -1;
105 }
106 
GetCipherSpecType(CipherSpecItem targetItemType)107 int32_t GetCipherSpecType(CipherSpecItem targetItemType)
108 {
109     if (targetItemType == OAEP_MD_NAME_STR || targetItemType == OAEP_MGF_NAME_STR ||
110         targetItemType == OAEP_MGF1_MD_STR || targetItemType == SM2_MD_NAME_STR) {
111         return SPEC_ITEM_TYPE_STR;
112     }
113     if (targetItemType == OAEP_MGF1_PSRC_UINT8ARR) {
114         return SPEC_ITEM_TYPE_UINT8ARR;
115     }
116     LOGE("CipherSpecItem not support! ItemType: %d", targetItemType);
117     return -1;
118 }
119 
NapiGetNull(napi_env env)120 napi_value NapiGetNull(napi_env env)
121 {
122     napi_value result = nullptr;
123     napi_get_null(env, &result);
124     return result;
125 }
126 
GetUint8ArrFromNapiDataBlob(napi_env env,napi_value arg)127 static napi_value GetUint8ArrFromNapiDataBlob(napi_env env, napi_value arg)
128 {
129     if ((env == nullptr) || (arg == nullptr)) {
130         LOGE("Invalid params!");
131         return nullptr;
132     }
133     napi_value data = nullptr;
134     napi_valuetype valueType = napi_undefined;
135     napi_status status = napi_get_named_property(env, arg, CRYPTO_TAG_DATA.c_str(), &data);
136     napi_typeof(env, data, &valueType);
137     if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
138         LOGE("failed to get valid data property!");
139         return nullptr;
140     }
141     return data;
142 }
143 
GetBlobFromNapiUint8Arr(napi_env env,napi_value data)144 HcfBlob *GetBlobFromNapiUint8Arr(napi_env env, napi_value data)
145 {
146     size_t length = 0;
147     size_t offset = 0;
148     void *rawData = nullptr;
149     napi_value arrayBuffer = nullptr;
150     napi_typedarray_type arrayType;
151     // Warning: Do not release the rawData returned by this interface because the rawData is managed by VM.
152     napi_status status = napi_get_typedarray_info(env, data, &arrayType, &length,
153         reinterpret_cast<void **>(&rawData), &arrayBuffer, &offset);
154     if ((status != napi_ok)) {
155         LOGE("failed to get valid rawData.");
156         return nullptr;
157     }
158     if (arrayType != napi_uint8_array) {
159         LOGE("input data is not uint8 array.");
160         return nullptr;
161     }
162 
163     HcfBlob *newBlob = reinterpret_cast<HcfBlob *>(HcfMalloc(sizeof(HcfBlob), 0));
164     if (newBlob == nullptr) {
165         LOGE("Failed to allocate newBlob memory!");
166         return nullptr;
167     }
168 
169     // input empty uint8Arr, ex: new Uint8Arr(), the length is 0 and rawData is nullptr;
170     if ((length == 0) || (rawData == nullptr)) {
171         newBlob->len = 0;
172         newBlob->data = nullptr;
173         LOGD("napi Uint8Arr is null");
174         return newBlob;
175     }
176     newBlob->len = length;
177     newBlob->data = static_cast<uint8_t *>(HcfMalloc(length, 0));
178     if (newBlob->data == nullptr) {
179         LOGE("malloc blob data failed!");
180         HcfFree(newBlob);
181         return nullptr;
182     }
183     (void)memcpy_s(newBlob->data, length, rawData, length);
184     return newBlob;
185 }
186 
GetBlobFromNapiDataBlob(napi_env env,napi_value arg)187 HcfBlob *GetBlobFromNapiDataBlob(napi_env env, napi_value arg)
188 {
189     napi_value data = GetUint8ArrFromNapiDataBlob(env, arg);
190     if (data == nullptr) {
191         LOGE("failed to get data in DataBlob");
192         return nullptr;
193     }
194     return GetBlobFromNapiUint8Arr(env, data);
195 }
196 
GetBlobFromNapiValue(napi_env env,napi_value arg,HcfBlob * blob)197 HcfResult GetBlobFromNapiValue(napi_env env, napi_value arg, HcfBlob *blob)
198 {
199     napi_value data = GetUint8ArrFromNapiDataBlob(env, arg);
200     if (data == nullptr) {
201         LOGE("failed to get data in DataBlob");
202         return HCF_INVALID_PARAMS;
203     }
204 
205     void *rawData = nullptr;
206     napi_typedarray_type arrayType;
207     napi_status status = napi_get_typedarray_info(env, data, &arrayType, &(blob->len),
208         reinterpret_cast<void **>(&rawData), nullptr, nullptr);
209     if (status != napi_ok) {
210         LOGE("failed to get valid rawData.");
211         return HCF_ERR_NAPI;
212     }
213     if (arrayType != napi_uint8_array) {
214         LOGE("input data is not uint8 array.");
215         return HCF_INVALID_PARAMS;
216     }
217 
218     blob->data = nullptr;
219     if (blob->len == 0 || rawData == nullptr) {
220         LOGD("napi Uint8Arr is null");
221         return HCF_SUCCESS;
222     }
223 
224     blob->data = static_cast<uint8_t *>(HcfMalloc(blob->len, 0));
225     if (blob->data == nullptr) {
226         LOGE("malloc blob data failed!");
227         return HCF_ERR_MALLOC;
228     }
229     (void)memcpy_s(blob->data, blob->len, rawData, blob->len);
230     return HCF_SUCCESS;
231 }
232 
GetAadFromParamsSpec(napi_env env,napi_value arg)233 static HcfBlob *GetAadFromParamsSpec(napi_env env, napi_value arg)
234 {
235     napi_value data = nullptr;
236     HcfBlob *blob = nullptr;
237     napi_valuetype valueType = napi_undefined;
238 
239     napi_status status = napi_get_named_property(env, arg, AAD_PARAMS.c_str(), &data);
240     napi_typeof(env, data, &valueType);
241     if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
242         LOGE("failed to get valid param property!");
243         return nullptr;
244     }
245     if (valueType == napi_null) {
246         blob = reinterpret_cast<HcfBlob *>(HcfMalloc(sizeof(HcfBlob), 0));
247         if (blob == nullptr) {
248             LOGE("Failed to allocate newBlob memory!");
249             return nullptr;
250         }
251         return blob;
252     }
253     blob = GetBlobFromNapiDataBlob(env, data);
254     if (blob == nullptr) {
255         LOGE("GetBlobFromNapiDataBlob failed!");
256         return nullptr;
257     }
258     return blob;
259 }
260 
GetBigIntFromNapiValue(napi_env env,napi_value arg,HcfBigInteger * bigInt)261 bool GetBigIntFromNapiValue(napi_env env, napi_value arg, HcfBigInteger *bigInt)
262 {
263     if ((env == nullptr) || (arg == nullptr) || (bigInt == nullptr)) {
264         LOGE("Invalid params!");
265         return false;
266     }
267 
268     int signBit;
269     size_t wordCount;
270 
271     napi_get_value_bigint_words(env, arg, nullptr, &wordCount, nullptr);
272     if ((wordCount == 0) || (wordCount > (INT_MAX / sizeof(uint64_t)))) {
273         LOGE("Get big int failed.");
274         return false;
275     }
276     int length = wordCount * sizeof(uint64_t);
277     uint8_t *retArr = reinterpret_cast<uint8_t *>(HcfMalloc(length, 0));
278     if (retArr == nullptr) {
279         LOGE("malloc blob data failed!");
280         return false;
281     }
282     if (napi_get_value_bigint_words(env, arg, &signBit, &wordCount, reinterpret_cast<uint64_t *>(retArr)) != napi_ok) {
283         HcfFree(retArr);
284         LOGE("failed to get valid rawData.");
285         return false;
286     }
287     if (signBit != 0) {
288         HcfFree(retArr);
289         LOGE("failed to get gegative rawData.");
290         return false;
291     }
292     bigInt->data = retArr;
293     bigInt->len = length;
294     return true;
295 }
296 
GetPointFromNapiValue(napi_env env,napi_value arg,HcfPoint * point)297 bool GetPointFromNapiValue(napi_env env, napi_value arg, HcfPoint *point)
298 {
299     if ((env == nullptr) || (arg == nullptr) || (point == nullptr)) {
300         LOGE("Invalid params!");
301         return false;
302     }
303     napi_value dataX = nullptr;
304     napi_value dataY = nullptr;
305     napi_valuetype valueType = napi_undefined;
306     napi_status status = napi_get_named_property(env, arg, "x", &dataX);
307     napi_typeof(env, dataX, &valueType);
308     if ((status != napi_ok) || (dataX == nullptr) || (valueType == napi_undefined)) {
309         LOGE("failed to get valid algo name!");
310         return false;
311     }
312     status = napi_get_named_property(env, arg, "y", &dataY);
313     napi_typeof(env, dataY, &valueType);
314     if ((status != napi_ok) || (dataY == nullptr) || (valueType == napi_undefined)) {
315         LOGE("failed to get valid algo name!");
316         return false;
317     }
318 
319     bool ret = GetBigIntFromNapiValue(env, dataX, &point->x);
320     if (!ret) {
321         LOGE("get point x failed!");
322         return false;
323     }
324     ret = GetBigIntFromNapiValue(env, dataY, &point->y);
325     if (!ret) {
326         LOGE("get point y failed!");
327         HcfFree((point->x).data);
328         (point->x).data = nullptr;
329         return false;
330     }
331     return true;
332 }
333 
GetIvParamsSpecType()334 static const char *GetIvParamsSpecType()
335 {
336     return IV_PARAMS_SPEC.c_str();
337 }
338 
GetGcmParamsSpecType()339 static const char *GetGcmParamsSpecType()
340 {
341     return GCM_PARAMS_SPEC.c_str();
342 }
343 
GetCcmParamsSpecType()344 static const char *GetCcmParamsSpecType()
345 {
346     return CCM_PARAMS_SPEC.c_str();
347 }
348 
GetBlobFromParamsSpec(napi_env env,napi_value arg,const string & type)349 static HcfBlob *GetBlobFromParamsSpec(napi_env env, napi_value arg, const string &type)
350 {
351     napi_value data = nullptr;
352     HcfBlob *blob = nullptr;
353     napi_valuetype valueType = napi_undefined;
354 
355     napi_status status = napi_get_named_property(env, arg, type.c_str(), &data);
356     napi_typeof(env, data, &valueType);
357     if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
358         LOGE("failed to get valid param property!");
359         return nullptr;
360     }
361     blob = GetBlobFromNapiDataBlob(env, data);
362     if (blob == nullptr) {
363         LOGE("GetBlobFromNapiDataBlob failed!");
364         return nullptr;
365     }
366     return blob;
367 }
368 
GetIvParamsSpec(napi_env env,napi_value arg,HcfParamsSpec ** paramsSpec)369 static bool GetIvParamsSpec(napi_env env, napi_value arg, HcfParamsSpec **paramsSpec)
370 {
371     HcfIvParamsSpec *ivParamsSpec = reinterpret_cast<HcfIvParamsSpec *>(HcfMalloc(sizeof(HcfIvParamsSpec), 0));
372     if (ivParamsSpec == nullptr) {
373         LOGE("ivParamsSpec malloc failed!");
374         return false;
375     }
376 
377     HcfBlob *iv = GetBlobFromParamsSpec(env, arg, IV_PARAMS);
378     if (iv == nullptr) {
379         LOGE("GetBlobFromNapiDataBlob failed!");
380         HcfFree(ivParamsSpec);
381         return false;
382     }
383     ivParamsSpec->base.getType = GetIvParamsSpecType;
384     ivParamsSpec->iv = *iv;
385     *paramsSpec = reinterpret_cast<HcfParamsSpec *>(ivParamsSpec);
386     HcfFree(iv);
387     return true;
388 }
389 
GetIvAndAadBlob(napi_env env,napi_value arg,HcfBlob ** iv,HcfBlob ** aad)390 static bool GetIvAndAadBlob(napi_env env, napi_value arg, HcfBlob **iv, HcfBlob **aad)
391 {
392     *iv = GetBlobFromParamsSpec(env, arg, IV_PARAMS);
393     if (*iv == nullptr) {
394         LOGE("get iv failed!");
395         return false;
396     }
397 
398     *aad = GetAadFromParamsSpec(env, arg);
399     // error case free is in get paramspec func.
400     if (*aad == nullptr) {
401         LOGE("get aad failed!");
402         return false;
403     }
404     return true;
405 }
406 
GetGcmParamsSpec(napi_env env,napi_value arg,HcfCryptoMode opMode,HcfParamsSpec ** paramsSpec)407 static bool GetGcmParamsSpec(napi_env env, napi_value arg, HcfCryptoMode opMode, HcfParamsSpec **paramsSpec)
408 {
409     HcfBlob *iv = nullptr;
410     HcfBlob *aad = nullptr;
411     HcfBlob *tag = nullptr;
412     HcfBlob authTag = {};
413     bool ret = false;
414 
415     HcfGcmParamsSpec *gcmParamsSpec = reinterpret_cast<HcfGcmParamsSpec *>(HcfMalloc(sizeof(HcfGcmParamsSpec), 0));
416     if (gcmParamsSpec == nullptr) {
417         LOGE("gcmParamsSpec malloc failed!");
418         return false;
419     }
420 
421     if (!GetIvAndAadBlob(env, arg, &iv, &aad)) {
422         LOGE("GetIvAndAadBlob failed!");
423         goto clearup;
424     }
425 
426     if (opMode == DECRYPT_MODE) {
427         tag = GetBlobFromParamsSpec(env, arg, AUTHTAG_PARAMS);
428         if (tag == nullptr) {
429             LOGE("get tag failed!");
430             goto clearup;
431         }
432     } else if (opMode == ENCRYPT_MODE) {
433         authTag.data = static_cast<uint8_t *>(HcfMalloc(GCM_AUTH_TAG_LEN, 0));
434         if (authTag.data == nullptr) {
435             LOGE("get tag failed!");
436             goto clearup;
437         }
438         authTag.len = GCM_AUTH_TAG_LEN;
439     } else {
440         goto clearup;
441     }
442 
443     gcmParamsSpec->base.getType = GetGcmParamsSpecType;
444     gcmParamsSpec->iv = *iv;
445     gcmParamsSpec->aad = *aad;
446     gcmParamsSpec->tag = opMode == DECRYPT_MODE ? *tag : authTag;
447     *paramsSpec = reinterpret_cast<HcfParamsSpec *>(gcmParamsSpec);
448     ret = true;
449 clearup:
450    if (!ret) {
451         HcfBlobDataFree(iv);
452         HcfBlobDataFree(aad);
453         HcfBlobDataFree(tag);
454         HcfFree(gcmParamsSpec);
455     }
456     HcfFree(iv);
457     HcfFree(aad);
458     HcfFree(tag);
459     return ret;
460 }
461 
GetCcmParamsSpec(napi_env env,napi_value arg,HcfCryptoMode opMode,HcfParamsSpec ** paramsSpec)462 static bool GetCcmParamsSpec(napi_env env, napi_value arg, HcfCryptoMode opMode, HcfParamsSpec **paramsSpec)
463 {
464     HcfBlob *iv = nullptr;
465     HcfBlob *aad = nullptr;
466     HcfBlob *tag = nullptr;
467     HcfBlob authTag = {};
468     bool ret = false;
469 
470     HcfCcmParamsSpec *ccmParamsSpec = reinterpret_cast<HcfCcmParamsSpec *>(HcfMalloc(sizeof(HcfCcmParamsSpec), 0));
471     if (ccmParamsSpec == nullptr) {
472         LOGE("ccmParamsSpec malloc failed!");
473         return ret;
474     }
475 
476     if (!GetIvAndAadBlob(env, arg, &iv, &aad)) {
477         LOGE("GetIvAndAadBlob failed!");
478         goto clearup;
479     }
480 
481     if (opMode == DECRYPT_MODE) {
482         tag = GetBlobFromParamsSpec(env, arg, AUTHTAG_PARAMS);
483         if (tag == nullptr) {
484             LOGE("get tag failed!");
485             goto clearup;
486         }
487     } else if (opMode == ENCRYPT_MODE) {
488         authTag.data = static_cast<uint8_t *>(HcfMalloc(CCM_AUTH_TAG_LEN, 0));
489         if (authTag.data == nullptr) {
490             LOGE("get tag failed!");
491             goto clearup;
492         }
493         authTag.len = CCM_AUTH_TAG_LEN;
494     } else {
495         goto clearup;
496     }
497     ccmParamsSpec->base.getType = GetCcmParamsSpecType;
498     ccmParamsSpec->iv = *iv;
499     ccmParamsSpec->aad = *aad;
500     ccmParamsSpec->tag = opMode == DECRYPT_MODE ? *tag : authTag;
501     *paramsSpec = reinterpret_cast<HcfParamsSpec *>(ccmParamsSpec);
502     ret = true;
503 clearup:
504     if (!ret) {
505         HcfBlobDataFree(iv);
506         HcfBlobDataFree(aad);
507         HcfBlobDataFree(tag);
508         HcfFree(ccmParamsSpec);
509     }
510     HcfFree(iv);
511     HcfFree(aad);
512     HcfFree(tag);
513     return ret;
514 }
515 
GetParamsSpecFromNapiValue(napi_env env,napi_value arg,HcfCryptoMode opMode,HcfParamsSpec ** paramsSpec)516 bool GetParamsSpecFromNapiValue(napi_env env, napi_value arg, HcfCryptoMode opMode, HcfParamsSpec **paramsSpec)
517 {
518     napi_value data = nullptr;
519     napi_valuetype valueType = napi_undefined;
520     if ((env == nullptr) || (arg == nullptr) || (paramsSpec == nullptr)) {
521         LOGE("Invalid params!");
522         return false;
523     }
524 
525     napi_status status = napi_get_named_property(env, arg, ALGO_PARAMS.c_str(), &data);
526     napi_typeof(env, data, &valueType);
527     if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
528         status = napi_get_named_property(env, arg, ALGO_PARAMS_OLD.c_str(), &data);
529         napi_typeof(env, data, &valueType);
530         if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
531             LOGE("failed to get valid algo name!");
532             return false;
533         }
534     }
535     string algoName;
536     if (!GetStringFromJSParams(env, data, algoName)) {
537         LOGE("GetStringFromJSParams failed!");
538         return false;
539     }
540     if (algoName.compare(IV_PARAMS_SPEC) == 0) {
541         return GetIvParamsSpec(env, arg, paramsSpec);
542     } else if (algoName.compare(GCM_PARAMS_SPEC) == 0) {
543         return GetGcmParamsSpec(env, arg, opMode, paramsSpec);
544     } else if (algoName.compare(CCM_PARAMS_SPEC) == 0) {
545         return GetCcmParamsSpec(env, arg, opMode, paramsSpec);
546     } else {
547         return false;
548     }
549 }
550 
GetCharArrayFromJsString(napi_env env,napi_value arg,HcfBlob * retBlob)551 static bool GetCharArrayFromJsString(napi_env env, napi_value arg, HcfBlob *retBlob)
552 {
553     size_t length = 0;
554     if (napi_get_value_string_utf8(env, arg, nullptr, 0, &length) != napi_ok) {
555         LOGE("can not get char string length");
556         return false;
557     }
558     if (length > PASSWORD_MAX_LENGTH) {
559         LOGE("password length should not exceed 4096");
560         return false;
561     }
562     if (length == 0) {
563         LOGD("empty string");
564         return false;
565     }
566     char *tmpPassword = static_cast<char *>(HcfMalloc(length + 1, 0));
567     if (tmpPassword == nullptr) {
568         LOGE("malloc string failed");
569         return false;
570     }
571     if (napi_get_value_string_utf8(env, arg, tmpPassword, (length + 1), &length) != napi_ok) {
572         LOGE("can not get char string value");
573         HcfFree(tmpPassword);
574         return false;
575     }
576     retBlob->data = reinterpret_cast<uint8_t *>(tmpPassword);
577     retBlob->len = length;
578     return true;
579 }
580 
InitEncodingParams(napi_env env,napi_value arg,HcfKeyEncodingParamsSpec * spec,HcfBlob * tmpPw,HcfBlob * tmpCipher)581 static bool InitEncodingParams(napi_env env, napi_value arg, HcfKeyEncodingParamsSpec *spec, HcfBlob *tmpPw,
582     HcfBlob *tmpCipher)
583 {
584     napi_value passWd = GetDetailAsyKeySpecValue(env, arg, PASSWD_PARAMS);
585     napi_value cipher = GetDetailAsyKeySpecValue(env, arg, CIPHER_PARAMS);
586     if ((passWd == nullptr) || (cipher == nullptr)) {
587         LOGE("Invalid params.");
588         return false;
589     }
590 
591     if (!GetCharArrayFromJsString(env, passWd, tmpPw)) {
592         LOGE("Failed to get passWord string from napi!");
593         return false;
594     }
595 
596     if (!GetCharArrayFromJsString(env, cipher, tmpCipher)) {
597         LOGE("Failed to get cipher string from napi!");
598         HcfBlobDataClearAndFree(tmpPw);
599         return false;
600     }
601 
602     spec->cipher = reinterpret_cast<char *>(tmpCipher->data);
603     spec->password = reinterpret_cast<char *>(tmpPw->data);
604     return true;
605 }
606 
GetEncodingParamsSpec(napi_env env,napi_value arg,HcfParamsSpec ** returnSpec)607 bool GetEncodingParamsSpec(napi_env env, napi_value arg, HcfParamsSpec **returnSpec)
608 {
609     if ((env == nullptr) || (arg == nullptr) || (returnSpec == nullptr)) {
610         LOGE("Invalid params.");
611         return false;
612     }
613 
614     HcfKeyEncodingParamsSpec *encodingParamsSpec =
615         reinterpret_cast<HcfKeyEncodingParamsSpec *>(HcfMalloc(sizeof(HcfKeyEncodingParamsSpec), 0));
616     if (encodingParamsSpec == nullptr) {
617         LOGE("encodingParamsSpec malloc failed!");
618         return false;
619     }
620 
621     HcfBlob tmpPw = { .data = nullptr, .len = 0 };
622     HcfBlob tmpCipher = { .data = nullptr, .len = 0 };
623     if (!InitEncodingParams(env, arg, encodingParamsSpec, &tmpPw, &tmpCipher)) {
624         LOGE("Failed to get passWord string from napi!");
625         HcfFree(encodingParamsSpec);
626         return false;
627     }
628     *returnSpec = reinterpret_cast<HcfParamsSpec *>(encodingParamsSpec);
629     return true;
630 }
631 
GetBlobFromStringJSParams(napi_env env,napi_value arg)632 static HcfBlob *GetBlobFromStringJSParams(napi_env env, napi_value arg)
633 {
634     napi_valuetype valueType;
635     napi_typeof(env, arg, &valueType);
636     if (valueType != napi_string) {
637         LOGE("wrong argument type. expect string type. [Type]: %d", valueType);
638         return nullptr;
639     }
640 
641     size_t length = 0;
642     if (napi_get_value_string_utf8(env, arg, nullptr, 0, &length) != napi_ok) {
643         LOGE("can not get string length");
644         return nullptr;
645     }
646 
647     if (length == 0) {
648         LOGE("string length is 0");
649         return nullptr;
650     }
651 
652     HcfBlob *newBlob = static_cast<HcfBlob *>(HcfMalloc(sizeof(HcfBlob), 0));
653     if (newBlob == nullptr) {
654         LOGE("Failed to allocate newBlob memory!");
655         return nullptr;
656     }
657 
658     newBlob->len = length + 1;
659     newBlob->data = static_cast<uint8_t *>(HcfMalloc(newBlob->len, 0));
660     if (newBlob->data == nullptr) {
661         LOGE("malloc blob data failed!");
662         HcfFree(newBlob);
663         return nullptr;
664     }
665 
666     if (napi_get_value_string_utf8(env, arg, reinterpret_cast<char *>(newBlob->data), newBlob->len, &length) !=
667         napi_ok) {
668         LOGE("can not get string value");
669         HcfBlobDataClearAndFree(newBlob);
670         HcfFree(newBlob);
671         return nullptr;
672     }
673 
674     return newBlob;
675 }
676 
GetDecodingParamsSpec(napi_env env,napi_value arg,HcfParamsSpec ** returnSpec)677 bool GetDecodingParamsSpec(napi_env env, napi_value arg, HcfParamsSpec **returnSpec)
678 {
679     HcfKeyDecodingParamsSpec *decodingParamsSpec =
680         reinterpret_cast<HcfKeyDecodingParamsSpec *>(HcfMalloc(sizeof(HcfKeyDecodingParamsSpec), 0));
681     if (decodingParamsSpec == nullptr) {
682         LOGE("decodingParamsSpec malloc failed!");
683         return false;
684     }
685 
686     HcfBlob *tmpPw = GetBlobFromStringJSParams(env, arg);
687     if (tmpPw == nullptr) {
688         LOGE("Failed to get passWord string from napi!");
689         HcfFree(decodingParamsSpec);
690         return false;
691     }
692     if (tmpPw->len > PASSWORD_MAX_LENGTH) {
693         LOGE("Password length exceeds max length limit of 4096 bytes!");
694         HcfBlobDataClearAndFree(tmpPw);
695         HcfFree(decodingParamsSpec);
696         return false;
697     }
698     decodingParamsSpec->password = reinterpret_cast<char *>(tmpPw->data);
699 
700     *returnSpec = reinterpret_cast<HcfParamsSpec *>(decodingParamsSpec);
701     HcfFree(tmpPw);
702     return true;
703 }
704 
GetDetailAsyKeySpecValue(napi_env env,napi_value arg,string argName)705 napi_value GetDetailAsyKeySpecValue(napi_env env, napi_value arg, string argName)
706 {
707     napi_value data = nullptr;
708     napi_valuetype valueType = napi_undefined;
709     if ((env == nullptr) || (arg == nullptr)) {
710         LOGE("Invalid params!");
711         return nullptr;
712     }
713     napi_status status = napi_get_named_property(env, arg, argName.c_str(), &data);
714     napi_typeof(env, data, &valueType);
715     if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
716         LOGE("failed to get valid algo name!");
717         return nullptr;
718     }
719     return data;
720 }
721 
GetCommSpecNapiValue(napi_env env,napi_value arg)722 static napi_value GetCommSpecNapiValue(napi_env env, napi_value arg)
723 {
724     napi_value data = nullptr;
725     napi_valuetype valueType = napi_undefined;
726 
727     napi_status status = napi_get_named_property(env, arg, CRYPTO_TAG_COMM_PARAMS.c_str(), &data);
728     napi_typeof(env, data, &valueType);
729 
730     if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
731         LOGE("failed to get valid algo name!");
732         return nullptr;
733     }
734     return data;
735 }
736 
InitDsaCommonAsyKeySpec(napi_env env,napi_value arg,HcfDsaCommParamsSpec * spec)737 static bool InitDsaCommonAsyKeySpec(napi_env env, napi_value arg, HcfDsaCommParamsSpec *spec)
738 {
739     size_t algNameLen = DSA_ASY_KEY_SPEC.length();
740     spec->base.algName = static_cast<char *>(HcfMalloc(algNameLen + 1, 0));
741     if (spec->base.algName == nullptr) {
742         LOGE("malloc DSA algName failed!");
743         return false;
744     }
745     (void)memcpy_s(spec->base.algName, algNameLen+ 1, DSA_ASY_KEY_SPEC.c_str(), algNameLen);
746     spec->base.specType = HCF_COMMON_PARAMS_SPEC;
747 
748     napi_value p = GetDetailAsyKeySpecValue(env, arg, "p");
749     napi_value q = GetDetailAsyKeySpecValue(env, arg, "q");
750     napi_value g = GetDetailAsyKeySpecValue(env, arg, "g");
751     bool ret = GetBigIntFromNapiValue(env, p, &spec->p);
752     if (!ret) {
753         HcfFree(spec->base.algName);
754         spec->base.algName = nullptr;
755         return false;
756     }
757     ret = GetBigIntFromNapiValue(env, q, &spec->q);
758     if (!ret) {
759         FreeDsaCommParamsSpec(spec);
760         return false;
761     }
762     ret = GetBigIntFromNapiValue(env, g, &spec->g);
763     if (!ret) {
764         FreeDsaCommParamsSpec(spec);
765         return false;
766     }
767     return true;
768 }
769 
GetDsaCommonAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)770 static bool GetDsaCommonAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
771 {
772     HcfDsaCommParamsSpec *spec = reinterpret_cast<HcfDsaCommParamsSpec *>(HcfMalloc(sizeof(HcfDsaCommParamsSpec), 0));
773     if (spec == nullptr) {
774         LOGE("malloc failed!");
775         return false;
776     }
777     if (!InitDsaCommonAsyKeySpec(env, arg, spec)) {
778         LOGE("InitDsaCommonAsyKeySpec failed!");
779         HcfFree(spec);
780         return false;
781     }
782     *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
783     return true;
784 }
785 
GetDsaPubKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)786 static bool GetDsaPubKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
787 {
788     HcfDsaPubKeyParamsSpec *spec = reinterpret_cast<HcfDsaPubKeyParamsSpec *>(
789         HcfMalloc(sizeof(HcfDsaPubKeyParamsSpec), 0));
790     if (spec == nullptr) {
791         LOGE("malloc failed!");
792         return false;
793     }
794 
795     napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
796     if (commSpecValue == nullptr) {
797         LOGE("Get comm spec napi value failed.");
798         HcfFree(spec);
799         return false;
800     }
801     if (!InitDsaCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfDsaCommParamsSpec *>(spec))) {
802         LOGE("InitDsaCommonAsyKeySpec failed.");
803         HcfFree(spec);
804         return false;
805     }
806     spec->base.base.specType = HCF_PUBLIC_KEY_SPEC;
807 
808     napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
809     bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk);
810     if (!ret) {
811         DestroyDsaPubKeySpec(spec);
812         return false;
813     }
814     *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
815     return true;
816 }
817 
GetDsaKeyPairAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)818 static bool GetDsaKeyPairAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
819 {
820     HcfDsaKeyPairParamsSpec *spec = reinterpret_cast<HcfDsaKeyPairParamsSpec *>(
821         HcfMalloc(sizeof(HcfDsaKeyPairParamsSpec), 0));
822     if (spec == nullptr) {
823         LOGE("malloc failed!");
824         return false;
825     }
826 
827     napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
828     if (commSpecValue == nullptr) {
829         LOGE("Get comm spec napi value failed.");
830         HcfFree(spec);
831         return false;
832     }
833     if (!InitDsaCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfDsaCommParamsSpec *>(spec))) {
834         LOGE("InitDsaCommonAsyKeySpec failed!");
835         HcfFree(spec);
836         return false;
837     }
838     spec->base.base.specType = HCF_KEY_PAIR_SPEC;
839 
840     napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
841     bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk);
842     if (!ret) {
843         FreeDsaCommParamsSpec(reinterpret_cast<HcfDsaCommParamsSpec *>(spec));
844         HcfFree(spec);
845         return false;
846     }
847     napi_value sk = GetDetailAsyKeySpecValue(env, arg, "sk");
848     ret = GetBigIntFromNapiValue(env, sk, &spec->sk);
849     if (!ret) {
850         FreeDsaCommParamsSpec(reinterpret_cast<HcfDsaCommParamsSpec *>(spec));
851         HcfFree(spec->pk.data);
852         HcfFree(spec);
853         return false;
854     }
855     *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
856     return true;
857 }
858 
GetDsaAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)859 static bool GetDsaAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
860 {
861     napi_value data = nullptr;
862     napi_valuetype valueType = napi_undefined;
863 
864     napi_status status = napi_get_named_property(env, arg, TAG_SPEC_TYPE.c_str(), &data);
865     napi_typeof(env, data, &valueType);
866     if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
867         LOGE("failed to get valid algo name!");
868         return false;
869     }
870     HcfAsyKeySpecType asyKeySpecType;
871     status = napi_get_value_uint32(env, data, reinterpret_cast<uint32_t *>(&asyKeySpecType));
872     if (status != napi_ok) {
873         LOGE("failed to get valid asyKeySpecType!");
874         return false;
875     }
876     if (asyKeySpecType == HCF_COMMON_PARAMS_SPEC) {
877         return GetDsaCommonAsyKeySpec(env, arg, asyKeySpec);
878     } else if (asyKeySpecType == HCF_PUBLIC_KEY_SPEC) {
879         return GetDsaPubKeySpec(env, arg, asyKeySpec);
880     } else if (asyKeySpecType == HCF_KEY_PAIR_SPEC) {
881         return GetDsaKeyPairAsyKeySpec(env, arg, asyKeySpec);
882     } else {
883         return false;
884     }
885 }
886 
GetFpField(napi_env env,napi_value arg,HcfECField ** ecField)887 static bool GetFpField(napi_env env, napi_value arg, HcfECField **ecField)
888 {
889     HcfECFieldFp *fp = reinterpret_cast<HcfECFieldFp *>(HcfMalloc(sizeof(HcfECFieldFp), 0));
890     if (fp == nullptr) {
891         LOGE("malloc fp failed!");
892         return false;
893     }
894 
895     size_t fieldTpyeLen = ECC_FIELD_TYPE_FP.length();
896     fp->base.fieldType = static_cast<char *>(HcfMalloc(fieldTpyeLen + 1, 0));
897     if (fp->base.fieldType == nullptr) {
898         LOGE("malloc fieldType failed!");
899         HcfFree(fp);
900         return false;
901     }
902     (void)memcpy_s(fp->base.fieldType, fieldTpyeLen+ 1, ECC_FIELD_TYPE_FP.c_str(), fieldTpyeLen);
903 
904     napi_value p = GetDetailAsyKeySpecValue(env, arg, "p");
905     bool ret = GetBigIntFromNapiValue(env, p, &fp->p);
906     if (!ret) {
907         HcfFree(fp->base.fieldType);
908         HcfFree(fp);
909         return false;
910     }
911     *ecField = reinterpret_cast<HcfECField *>(fp);
912     return true;
913 }
914 
GetField(napi_env env,napi_value arg,HcfECField ** ecField)915 static bool GetField(napi_env env, napi_value arg, HcfECField **ecField)
916 {
917     // get fieldData in { field : fieldData, a : xxx, b : xxx, ... } of ECCCommonParamsSpec first
918     napi_value fieldData = nullptr;
919     napi_valuetype valueType = napi_undefined;
920     napi_status status = napi_get_named_property(env, arg, "field", &fieldData);
921     napi_typeof(env, fieldData, &valueType);
922     if ((status != napi_ok) || (fieldData == nullptr) || (valueType == napi_undefined)) {
923         LOGE("failed to get valid field data!");
924         return false;
925     }
926 
927     // get fieldType in { fieldType : fieldTypeData } of ECField
928     napi_value fieldTypeData = nullptr;
929     status = napi_get_named_property(env, fieldData, "fieldType", &fieldTypeData);
930     napi_typeof(env, fieldTypeData, &valueType);
931     if ((status != napi_ok) || (fieldTypeData == nullptr) || (valueType == napi_undefined)) {
932         LOGE("failed to get valid fieldType data!");
933         return false;
934     }
935     string fieldType;
936     if (!GetStringFromJSParams(env, fieldTypeData, fieldType)) {
937         LOGE("GetStringFromJSParams failed when extracting fieldType!");
938         return false;
939     }
940 
941     // get p in { p : pData } of ECField, and generateECField
942     if (fieldType.compare("Fp") == 0) {
943         return GetFpField(env, fieldData, ecField);
944     }
945     return false;
946 }
947 
InitEccDetailAsyKeySpec(napi_env env,napi_value arg,HcfEccCommParamsSpec * spec)948 static bool InitEccDetailAsyKeySpec(napi_env env, napi_value arg, HcfEccCommParamsSpec *spec)
949 {
950     napi_value a = GetDetailAsyKeySpecValue(env, arg, "a");
951     napi_value b = GetDetailAsyKeySpecValue(env, arg, "b");
952     napi_value n = GetDetailAsyKeySpecValue(env, arg, "n");
953     napi_value g = GetDetailAsyKeySpecValue(env, arg, "g");
954     bool ret = GetBigIntFromNapiValue(env, a, &spec->a);
955     if (!ret) {
956         LOGE("get ecc asyKeySpec a failed!");
957         return false;
958     }
959     ret = GetBigIntFromNapiValue(env, b, &spec->b);
960     if (!ret) {
961         LOGE("get ecc asyKeySpec b failed!");
962         return false;
963     }
964     ret = GetBigIntFromNapiValue(env, n, &spec->n);
965     if (!ret) {
966         LOGE("get ecc asyKeySpec n failed!");
967         return false;
968     }
969     ret = GetPointFromNapiValue(env, g, &spec->g);
970     if (!ret) {
971         LOGE("get ecc asyKeySpec g failed!");
972         return false;
973     }
974     return true;
975 }
976 
InitEccCommonAsyKeySpec(napi_env env,napi_value arg,HcfEccCommParamsSpec * spec,const string & algName)977 static bool InitEccCommonAsyKeySpec(napi_env env, napi_value arg, HcfEccCommParamsSpec *spec, const string &algName)
978 {
979     size_t algNameLen = ECC_ASY_KEY_SPEC.length();
980     spec->base.algName = static_cast<char *>(HcfMalloc(algNameLen + 1, 0));
981     if (spec->base.algName == nullptr) {
982         LOGE("malloc ECC algName failed!");
983         return false;
984     }
985     (void)memcpy_s(spec->base.algName, algNameLen+ 1, algName.c_str(), algNameLen);
986     spec->base.specType = HCF_COMMON_PARAMS_SPEC;
987 
988     // get h
989     napi_value hData = nullptr;
990     napi_valuetype valueType = napi_undefined;
991     napi_status status = napi_get_named_property(env, arg, "h", &hData);
992     napi_typeof(env, hData, &valueType);
993     if ((status != napi_ok) || (hData == nullptr) || (valueType == napi_undefined)) {
994         LOGE("failed to get valid h!");
995         HcfFree(spec->base.algName);
996         spec->base.algName = nullptr;
997         return false;
998     }
999     if (!GetInt32FromJSParams(env, hData, spec->h)) {
1000         LOGE("get ecc asyKeySpec h failed!");
1001         HcfFree(spec->base.algName);
1002         spec->base.algName = nullptr;
1003         return false;
1004     }
1005     // get field
1006     if (!GetField(env, arg, &spec->field)) {
1007         LOGE("GetField failed!");
1008         HcfFree(spec->base.algName);
1009         spec->base.algName = nullptr;
1010         return false;
1011     }
1012     bool ret = InitEccDetailAsyKeySpec(env, arg, spec);
1013     if (!ret) {
1014         LOGE("get ecc asyKeySpec g failed!");
1015         FreeEccCommParamsSpec(spec);
1016         return false;
1017     }
1018     return true;
1019 }
1020 
GetEccCommonAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec,const string & algName)1021 static bool GetEccCommonAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec,
1022     const string &algName)
1023 {
1024     HcfEccCommParamsSpec *spec = reinterpret_cast<HcfEccCommParamsSpec *>(HcfMalloc(sizeof(HcfEccCommParamsSpec), 0));
1025     if (spec == nullptr) {
1026         LOGE("malloc failed!");
1027         return false;
1028     }
1029     if (!InitEccCommonAsyKeySpec(env, arg, spec, algName)) {
1030         LOGE("InitEccCommonAsyKeySpec failed!");
1031         HcfFree(spec);
1032         return false;
1033     }
1034     *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1035     return true;
1036 }
1037 
GetEccPriKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec,const string & algName)1038 static bool GetEccPriKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec, const string &algName)
1039 {
1040     HcfEccPriKeyParamsSpec *spec =
1041         reinterpret_cast<HcfEccPriKeyParamsSpec *>(HcfMalloc(sizeof(HcfEccPriKeyParamsSpec), 0));
1042     if (spec == nullptr) {
1043         LOGE("malloc failed!");
1044         return false;
1045     }
1046 
1047     napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
1048     if (commSpecValue == nullptr) {
1049         LOGE("Get comm spec napi value failed.");
1050         HcfFree(spec);
1051         return false;
1052     }
1053     if (!InitEccCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfEccCommParamsSpec *>(spec), algName)) {
1054         LOGE("InitEccCommonAsyKeySpec failed!");
1055         HcfFree(spec);
1056         return false;
1057     }
1058     spec->base.base.specType = HCF_PRIVATE_KEY_SPEC;
1059 
1060     napi_value sk = GetDetailAsyKeySpecValue(env, arg, "sk");
1061     bool ret = GetBigIntFromNapiValue(env, sk, &spec->sk);
1062     if (!ret) {
1063         // get big int fail, sk is null
1064         FreeEccCommParamsSpec(reinterpret_cast<HcfEccCommParamsSpec *>(spec));
1065         HcfFree(spec);
1066         return false;
1067     }
1068     *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1069     return true;
1070 }
1071 
GetEccPubKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec,const string & algName)1072 static bool GetEccPubKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec, const string &algName)
1073 {
1074     HcfEccPubKeyParamsSpec *spec =
1075         reinterpret_cast<HcfEccPubKeyParamsSpec *>(HcfMalloc(sizeof(HcfEccPubKeyParamsSpec), 0));
1076     if (spec == nullptr) {
1077         LOGE("malloc failed!");
1078         return false;
1079     }
1080 
1081     napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
1082     if (commSpecValue == nullptr) {
1083         LOGE("Get comm spec napi value failed.");
1084         HcfFree(spec);
1085         return false;
1086     }
1087     if (!InitEccCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfEccCommParamsSpec *>(spec), algName)) {
1088         LOGE("InitEccCommonAsyKeySpec failed!");
1089         HcfFree(spec);
1090         return false;
1091     }
1092     spec->base.base.specType = HCF_PUBLIC_KEY_SPEC;
1093 
1094     napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
1095     bool ret = GetPointFromNapiValue(env, pk, &spec->pk);
1096     if (!ret) {
1097         DestroyEccPubKeySpec(spec);
1098         return false;
1099     }
1100     *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1101     return true;
1102 }
1103 
GetEccKeyPairAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec,const string & algName)1104 static bool GetEccKeyPairAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec,
1105     const string &algName)
1106 {
1107     HcfEccKeyPairParamsSpec *spec =
1108         reinterpret_cast<HcfEccKeyPairParamsSpec *>(HcfMalloc(sizeof(HcfEccKeyPairParamsSpec), 0));
1109     if (spec == nullptr) {
1110         LOGE("malloc failed!");
1111         return false;
1112     }
1113 
1114     napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
1115     if (commSpecValue == nullptr) {
1116         LOGE("Get comm spec napi value failed.");
1117         HcfFree(spec);
1118         return false;
1119     }
1120     if (!InitEccCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfEccCommParamsSpec *>(spec), algName)) {
1121         LOGE("InitEccCommonAsyKeySpec failed!");
1122         HcfFree(spec);
1123         return false;
1124     }
1125     spec->base.base.specType = HCF_KEY_PAIR_SPEC;
1126 
1127     // get big int fail, sk is null
1128     napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
1129     bool ret = GetPointFromNapiValue(env, pk, &spec->pk);
1130     if (!ret) {
1131         FreeEccCommParamsSpec(reinterpret_cast<HcfEccCommParamsSpec *>(spec));
1132         HcfFree(spec);
1133         return false;
1134     }
1135     napi_value sk = GetDetailAsyKeySpecValue(env, arg, "sk");
1136     ret = GetBigIntFromNapiValue(env, sk, &spec->sk);
1137     if (!ret) {
1138         FreeEccCommParamsSpec(reinterpret_cast<HcfEccCommParamsSpec *>(spec));
1139         HcfFree(spec->pk.x.data);
1140         HcfFree(spec->pk.y.data);
1141         HcfFree(spec);
1142         return false;
1143     }
1144     *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1145     return true;
1146 }
1147 
GetEccAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec,const string & algName)1148 static bool GetEccAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec, const string &algName)
1149 {
1150     napi_value data = nullptr;
1151     napi_valuetype valueType = napi_undefined;
1152 
1153     napi_status status = napi_get_named_property(env, arg, TAG_SPEC_TYPE.c_str(), &data);
1154     napi_typeof(env, data, &valueType);
1155     if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
1156         LOGE("failed to get valid algo name!");
1157         return false;
1158     }
1159     HcfAsyKeySpecType asyKeySpecType;
1160     status = napi_get_value_uint32(env, data, reinterpret_cast<uint32_t *>(&asyKeySpecType));
1161     if (status != napi_ok) {
1162         LOGE("failed to get valid asyKeySpecType!");
1163         return false;
1164     }
1165     if (asyKeySpecType == HCF_COMMON_PARAMS_SPEC) {
1166         return GetEccCommonAsyKeySpec(env, arg, asyKeySpec, algName);
1167     } else if (asyKeySpecType == HCF_PRIVATE_KEY_SPEC) {
1168         return GetEccPriKeySpec(env, arg, asyKeySpec, algName);
1169     } else if (asyKeySpecType == HCF_PUBLIC_KEY_SPEC) {
1170         return GetEccPubKeySpec(env, arg, asyKeySpec, algName);
1171     } else if (asyKeySpecType == HCF_KEY_PAIR_SPEC) {
1172         return GetEccKeyPairAsyKeySpec(env, arg, asyKeySpec, algName);
1173     } else {
1174         LOGE("keySpec not support!");
1175         return false;
1176     }
1177 }
1178 
InitRsaCommonAsyKeySpec(napi_env env,napi_value arg,HcfRsaCommParamsSpec * spec)1179 static bool InitRsaCommonAsyKeySpec(napi_env env, napi_value arg, HcfRsaCommParamsSpec *spec)
1180 {
1181     size_t algNameLen = RSA_ASY_KEY_SPEC.length();
1182     spec->base.algName = static_cast<char *>(HcfMalloc(algNameLen + 1, 0));
1183     if (spec->base.algName == nullptr) {
1184         LOGE("malloc RSA algName failed!");
1185         return false;
1186     }
1187     (void)memcpy_s(spec->base.algName, algNameLen+ 1, RSA_ASY_KEY_SPEC.c_str(), algNameLen);
1188     spec->base.specType = HCF_COMMON_PARAMS_SPEC;
1189 
1190     napi_value n = GetDetailAsyKeySpecValue(env, arg, "n");
1191 
1192     bool ret = GetBigIntFromNapiValue(env, n, &spec->n);
1193     if (!ret) {
1194         LOGE("Rsa asyKeySpec get n failed!");
1195         HcfFree(spec->base.algName);
1196         spec->base.algName = nullptr;
1197         return false;
1198     }
1199     return true;
1200 }
1201 
GetRsaPubKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)1202 static bool GetRsaPubKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
1203 {
1204     HcfRsaPubKeyParamsSpec *spec =
1205         reinterpret_cast<HcfRsaPubKeyParamsSpec *>(HcfMalloc(sizeof(HcfRsaPubKeyParamsSpec), 0));
1206     if (spec == nullptr) {
1207         LOGE("malloc failed!");
1208         return false;
1209     }
1210 
1211     napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
1212     if (commSpecValue == nullptr) {
1213         LOGE("Get comm spec napi value failed.");
1214         HcfFree(spec);
1215         return false;
1216     }
1217     if (!InitRsaCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfRsaCommParamsSpec *>(spec))) {
1218         LOGE("InitRsaCommonAsyKeySpec failed!");
1219         HcfFree(spec);
1220         return false;
1221     }
1222     spec->base.base.specType = HCF_PUBLIC_KEY_SPEC;
1223 
1224     napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
1225     bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk);
1226     if (!ret) {
1227         DestroyRsaPubKeySpec(spec);
1228         return false;
1229     }
1230     *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1231     return true;
1232 }
1233 
GetRsaKeyPairAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)1234 static bool GetRsaKeyPairAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
1235 {
1236     HcfRsaKeyPairParamsSpec *spec =
1237         reinterpret_cast<HcfRsaKeyPairParamsSpec *>(HcfMalloc(sizeof(HcfRsaKeyPairParamsSpec), 0));
1238     if (spec == nullptr) {
1239         LOGE("malloc failed!");
1240         return false;
1241     }
1242 
1243     napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
1244     if (commSpecValue == nullptr) {
1245         LOGE("Get comm spec napi value failed.");
1246         HcfFree(spec);
1247         return false;
1248     }
1249     if (!InitRsaCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfRsaCommParamsSpec *>(spec))) {
1250         LOGE("InitRsaCommonAsyKeySpec failed!");
1251         HcfFree(spec);
1252         return false;
1253     }
1254     spec->base.base.specType = HCF_KEY_PAIR_SPEC;
1255 
1256     napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
1257     bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk);
1258     if (!ret) {
1259         FreeRsaCommParamsSpec(&(spec->base));
1260         HcfFree(spec);
1261         return false;
1262     }
1263     napi_value sk = GetDetailAsyKeySpecValue(env, arg, "sk");
1264     ret = GetBigIntFromNapiValue(env, sk, &spec->sk);
1265     if (!ret) {
1266         FreeRsaCommParamsSpec(&(spec->base));
1267         HcfFree(spec->pk.data);
1268         HcfFree(spec);
1269         return false;
1270     }
1271     *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1272     return true;
1273 }
1274 
GetRsaAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)1275 static bool GetRsaAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
1276 {
1277     napi_value data = nullptr;
1278     napi_valuetype valueType = napi_undefined;
1279 
1280     napi_status status = napi_get_named_property(env, arg, TAG_SPEC_TYPE.c_str(), &data);
1281     napi_typeof(env, data, &valueType);
1282     if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
1283         LOGE("failed to get valid algo name!");
1284         return false;
1285     }
1286     HcfAsyKeySpecType asyKeySpecType;
1287     status = napi_get_value_uint32(env, data, reinterpret_cast<uint32_t *>(&asyKeySpecType));
1288     if (status != napi_ok) {
1289         LOGE("failed to get valid asyKeySpecType!");
1290         return false;
1291     }
1292     if (asyKeySpecType == HCF_COMMON_PARAMS_SPEC) {
1293         LOGE("RSA not support comm key spec");
1294         return false;
1295     } else if (asyKeySpecType == HCF_PUBLIC_KEY_SPEC) {
1296         return GetRsaPubKeySpec(env, arg, asyKeySpec);
1297     } else if (asyKeySpecType == HCF_KEY_PAIR_SPEC) {
1298         return GetRsaKeyPairAsyKeySpec(env, arg, asyKeySpec);
1299     } else {
1300         return false;
1301     }
1302 }
1303 
InitAlg25519CommonAsyKeySpec(HcfAsyKeyParamsSpec * spec,const string & algName)1304 static bool InitAlg25519CommonAsyKeySpec(HcfAsyKeyParamsSpec *spec, const string &algName)
1305 {
1306     size_t algNameLen = algName.length();
1307     spec->algName = static_cast<char *>(HcfMalloc(algNameLen + 1, 0));
1308     if (spec->algName == nullptr) {
1309         LOGE("malloc alg25519 algName failed!");
1310         return false;
1311     }
1312     (void)memcpy_s(spec->algName, algNameLen + 1, algName.c_str(), algNameLen);
1313     return true;
1314 }
1315 
GetAlg25519PriKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec,const string & algName)1316 static bool GetAlg25519PriKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec, const string &algName)
1317 {
1318     HcfAlg25519PriKeyParamsSpec *spec =
1319         reinterpret_cast<HcfAlg25519PriKeyParamsSpec *>(HcfMalloc(sizeof(HcfAlg25519PriKeyParamsSpec), 0));
1320     if (spec == nullptr) {
1321         LOGE("malloc failed!");
1322         return false;
1323     }
1324     if (!InitAlg25519CommonAsyKeySpec(reinterpret_cast<HcfAsyKeyParamsSpec *>(spec), algName)) {
1325         LOGE("InitRsaCommonAsyKeySpec failed!");
1326         DestroyAlg25519PriKeySpec(spec);
1327         return false;
1328     }
1329     spec->base.specType = HCF_PRIVATE_KEY_SPEC;
1330 
1331     napi_value sk = GetDetailAsyKeySpecValue(env, arg, "sk");
1332     bool ret = GetBigIntFromNapiValue(env, sk, &spec->sk);
1333     if (!ret) {
1334         // get big int fail, sk is null
1335         DestroyAlg25519PriKeySpec(spec);
1336         return false;
1337     }
1338     *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1339     return true;
1340 }
1341 
GetAlg25519PubKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec,const string & algName)1342 static bool GetAlg25519PubKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec, const string &algName)
1343 {
1344     HcfAlg25519PubKeyParamsSpec *spec =
1345         reinterpret_cast<HcfAlg25519PubKeyParamsSpec *>(HcfMalloc(sizeof(HcfAlg25519PubKeyParamsSpec), 0));
1346     if (spec == nullptr) {
1347         LOGE("malloc failed!");
1348         return false;
1349     }
1350     if (!InitAlg25519CommonAsyKeySpec(reinterpret_cast<HcfAsyKeyParamsSpec *>(spec), algName)) {
1351         LOGE("InitRsaCommonAsyKeySpec failed!");
1352         DestroyAlg25519PubKeySpec(spec);
1353         return false;
1354     }
1355     spec->base.specType = HCF_PUBLIC_KEY_SPEC;
1356 
1357     napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
1358     bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk);
1359     if (!ret) {
1360         DestroyAlg25519PubKeySpec(spec);
1361         return false;
1362     }
1363     *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1364     return true;
1365 }
1366 
GetAlg25519KeyPairAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec,const string & algName)1367 static bool GetAlg25519KeyPairAsyKeySpec(napi_env env, napi_value arg,
1368     HcfAsyKeyParamsSpec **asyKeySpec, const string &algName)
1369 {
1370     HcfAlg25519KeyPairParamsSpec *spec =
1371         reinterpret_cast<HcfAlg25519KeyPairParamsSpec *>(HcfMalloc(sizeof(HcfAlg25519KeyPairParamsSpec), 0));
1372     if (spec == nullptr) {
1373         LOGE("malloc failed!");
1374         return false;
1375     }
1376     if (!InitAlg25519CommonAsyKeySpec(reinterpret_cast<HcfAsyKeyParamsSpec *>(spec), algName)) {
1377         LOGE("InitRsaCommonAsyKeySpec failed!");
1378         HcfFree(spec);
1379         return false;
1380     }
1381     spec->base.specType = HCF_KEY_PAIR_SPEC;
1382 
1383     // get big int fail, sk is null
1384     napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
1385     bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk);
1386     if (!ret) {
1387         DestroyAlg25519KeyPairSpec(spec);
1388         return false;
1389     }
1390     napi_value sk = GetDetailAsyKeySpecValue(env, arg, "sk");
1391     ret = GetBigIntFromNapiValue(env, sk, &spec->sk);
1392     if (!ret) {
1393         DestroyAlg25519KeyPairSpec(spec);
1394         return false;
1395     }
1396     *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1397     return true;
1398 }
1399 
GetAlg25519AsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec,const string & algName)1400 static bool GetAlg25519AsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec, const string &algName)
1401 {
1402     napi_value data = nullptr;
1403     napi_valuetype valueType = napi_undefined;
1404 
1405     napi_status status = napi_get_named_property(env, arg, TAG_SPEC_TYPE.c_str(), &data);
1406     napi_typeof(env, data, &valueType);
1407     if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
1408         LOGE("failed to get valid algo name!");
1409         return false;
1410     }
1411     HcfAsyKeySpecType asyKeySpecType;
1412     status = napi_get_value_uint32(env, data, reinterpret_cast<uint32_t *>(&asyKeySpecType));
1413     if (status != napi_ok) {
1414         LOGE("failed to get valid asyKeySpecType!");
1415         return false;
1416     }
1417     if (asyKeySpecType == HCF_PRIVATE_KEY_SPEC) {
1418         return GetAlg25519PriKeySpec(env, arg, asyKeySpec, algName);
1419     } else if (asyKeySpecType == HCF_PUBLIC_KEY_SPEC) {
1420         return GetAlg25519PubKeySpec(env, arg, asyKeySpec, algName);
1421     } else if (asyKeySpecType == HCF_KEY_PAIR_SPEC) {
1422         return GetAlg25519KeyPairAsyKeySpec(env, arg, asyKeySpec, algName);
1423     } else {
1424         LOGE("keySpec not support!");
1425         return false;
1426     }
1427 }
1428 
InitDhCommonAsyKeySpec(napi_env env,napi_value arg,HcfDhCommParamsSpec * spec)1429 static bool InitDhCommonAsyKeySpec(napi_env env, napi_value arg, HcfDhCommParamsSpec *spec)
1430 {
1431     size_t algNameLen = DH_ASY_KEY_SPEC.length();
1432     spec->base.algName = static_cast<char *>(HcfMalloc(algNameLen + 1, 0));
1433     if (spec->base.algName == nullptr) {
1434         LOGE("malloc DH algName failed!");
1435         return false;
1436     }
1437     (void)memcpy_s(spec->base.algName, algNameLen+ 1, DH_ASY_KEY_SPEC.c_str(), algNameLen);
1438     spec->base.specType = HCF_COMMON_PARAMS_SPEC;
1439 
1440     napi_value length = nullptr;
1441     napi_valuetype valueType = napi_undefined;
1442     napi_status status = napi_get_named_property(env, arg, "l", &length);
1443     napi_typeof(env, length, &valueType);
1444     if ((status != napi_ok) || (length == nullptr) || (valueType == napi_undefined)) {
1445         LOGE("failed to get valid l!");
1446         HcfFree(spec->base.algName);
1447         spec->base.algName = nullptr;
1448         return false;
1449     }
1450     if (!GetInt32FromJSParams(env, length, spec->length)) {
1451         LOGE("get dh asyKeySpec length failed!");
1452         HcfFree(spec->base.algName);
1453         spec->base.algName = nullptr;
1454         return false;
1455     }
1456     napi_value p = GetDetailAsyKeySpecValue(env, arg, "p");
1457     napi_value g = GetDetailAsyKeySpecValue(env, arg, "g");
1458     bool ret = GetBigIntFromNapiValue(env, p, &spec->p);
1459     if (!ret) {
1460         HcfFree(spec->base.algName);
1461         spec->base.algName = nullptr;
1462         return false;
1463     }
1464     ret = GetBigIntFromNapiValue(env, g, &spec->g);
1465     if (!ret) {
1466         FreeDhCommParamsSpec(spec);
1467         return false;
1468     }
1469     return true;
1470 }
1471 
GetDhCommonAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)1472 static bool GetDhCommonAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
1473 {
1474     HcfDhCommParamsSpec *spec = reinterpret_cast<HcfDhCommParamsSpec *>(HcfMalloc(sizeof(HcfDhCommParamsSpec), 0));
1475     if (spec == nullptr) {
1476         LOGE("malloc failed!");
1477         return false;
1478     }
1479     if (!InitDhCommonAsyKeySpec(env, arg, spec)) {
1480         LOGE("InitDhCommonAsyKeySpec failed!");
1481         HcfFree(spec);
1482         return false;
1483     }
1484     *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1485     return true;
1486 }
1487 
GetDhPubKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)1488 static bool GetDhPubKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
1489 {
1490     HcfDhPubKeyParamsSpec *spec = reinterpret_cast<HcfDhPubKeyParamsSpec *>(
1491         HcfMalloc(sizeof(HcfDhPubKeyParamsSpec), 0));
1492     if (spec == nullptr) {
1493         LOGE("malloc failed!");
1494         return false;
1495     }
1496 
1497     napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
1498     if (commSpecValue == nullptr) {
1499         LOGE("Get comm spec napi value failed.");
1500         HcfFree(spec);
1501         return false;
1502     }
1503     if (!InitDhCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfDhCommParamsSpec *>(spec))) {
1504         LOGE("InitDhCommonAsyKeySpec failed.");
1505         HcfFree(spec);
1506         return false;
1507     }
1508     spec->base.base.specType = HCF_PUBLIC_KEY_SPEC;
1509 
1510     napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
1511     bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk);
1512     if (!ret) {
1513         DestroyDhPubKeySpec(spec);
1514         return false;
1515     }
1516     *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1517     return true;
1518 }
1519 
GetDhPriKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)1520 static bool GetDhPriKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
1521 {
1522     HcfDhPriKeyParamsSpec *spec = reinterpret_cast<HcfDhPriKeyParamsSpec *>(
1523         HcfMalloc(sizeof(HcfDhPriKeyParamsSpec), 0));
1524     if (spec == nullptr) {
1525         LOGE("malloc failed!");
1526         return false;
1527     }
1528 
1529     napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
1530     if (commSpecValue == nullptr) {
1531         LOGE("Get comm spec napi value failed.");
1532         HcfFree(spec);
1533         return false;
1534     }
1535     if (!InitDhCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfDhCommParamsSpec *>(spec))) {
1536         LOGE("InitDhCommonAsyKeySpec failed.");
1537         HcfFree(spec);
1538         return false;
1539     }
1540     spec->base.base.specType = HCF_PRIVATE_KEY_SPEC;
1541 
1542     napi_value pk = GetDetailAsyKeySpecValue(env, arg, "sk");
1543     bool ret = GetBigIntFromNapiValue(env, pk, &spec->sk);
1544     if (!ret) {
1545         DestroyDhPriKeySpec(spec);
1546         return false;
1547     }
1548     *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1549     return true;
1550 }
1551 
GetDhKeyPairAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)1552 static bool GetDhKeyPairAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
1553 {
1554     HcfDhKeyPairParamsSpec *spec = reinterpret_cast<HcfDhKeyPairParamsSpec *>(
1555         HcfMalloc(sizeof(HcfDhKeyPairParamsSpec), 0));
1556     if (spec == nullptr) {
1557         LOGE("malloc failed!");
1558         return false;
1559     }
1560 
1561     napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
1562     if (commSpecValue == nullptr) {
1563         LOGE("Get comm spec napi value failed.");
1564         HcfFree(spec);
1565         return false;
1566     }
1567     if (!InitDhCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfDhCommParamsSpec *>(spec))) {
1568         LOGE("InitDhCommonAsyKeySpec failed!");
1569         HcfFree(spec);
1570         return false;
1571     }
1572     spec->base.base.specType = HCF_KEY_PAIR_SPEC;
1573 
1574     napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
1575     bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk);
1576     if (!ret) {
1577         FreeDhCommParamsSpec(reinterpret_cast<HcfDhCommParamsSpec *>(spec));
1578         HcfFree(spec);
1579         return false;
1580     }
1581     napi_value sk = GetDetailAsyKeySpecValue(env, arg, "sk");
1582     ret = GetBigIntFromNapiValue(env, sk, &spec->sk);
1583     if (!ret) {
1584         FreeDhCommParamsSpec(reinterpret_cast<HcfDhCommParamsSpec *>(spec));
1585         HcfFree(spec->pk.data);
1586         HcfFree(spec);
1587         return false;
1588     }
1589     *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1590     return true;
1591 }
1592 
GetDh25519AsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)1593 static bool GetDh25519AsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
1594 {
1595     napi_value data = nullptr;
1596     napi_valuetype valueType = napi_undefined;
1597 
1598     napi_status status = napi_get_named_property(env, arg, TAG_SPEC_TYPE.c_str(), &data);
1599     napi_typeof(env, data, &valueType);
1600     if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
1601         LOGE("failed to get valid algo name!");
1602         return false;
1603     }
1604     HcfAsyKeySpecType asyKeySpecType;
1605     status = napi_get_value_uint32(env, data, reinterpret_cast<uint32_t *>(&asyKeySpecType));
1606     if (status != napi_ok) {
1607         LOGE("failed to get valid asyKeySpecType!");
1608         return false;
1609     }
1610     if (asyKeySpecType == HCF_PRIVATE_KEY_SPEC) {
1611         return GetDhPriKeySpec(env, arg, asyKeySpec);
1612     } else if (asyKeySpecType == HCF_PUBLIC_KEY_SPEC) {
1613         return GetDhPubKeySpec(env, arg, asyKeySpec);
1614     } else if (asyKeySpecType == HCF_KEY_PAIR_SPEC) {
1615         return GetDhKeyPairAsyKeySpec(env, arg, asyKeySpec);
1616     } else if (asyKeySpecType == HCF_COMMON_PARAMS_SPEC) {
1617         return GetDhCommonAsyKeySpec(env, arg, asyKeySpec);
1618     } else {
1619         LOGE("keySpec not support!");
1620         return false;
1621     }
1622 }
1623 
GetAsyKeySpecFromNapiValue(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)1624 bool GetAsyKeySpecFromNapiValue(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
1625 {
1626     napi_value data = nullptr;
1627 
1628     if ((env == nullptr) || (arg == nullptr) || (asyKeySpec == nullptr)) {
1629         LOGE("Invalid params!");
1630         return false;
1631     }
1632 
1633     napi_valuetype valueType = napi_undefined;
1634 
1635     napi_status status = napi_get_named_property(env, arg, CRYPTO_TAG_ALG_NAME.c_str(), &data);
1636     napi_typeof(env, data, &valueType);
1637     if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
1638         LOGE("failed to get valid algName!");
1639         return false;
1640     }
1641     string algName;
1642     if (!GetStringFromJSParams(env, data, algName)) {
1643         LOGE("GetStringFromJSParams failed!");
1644         return false;
1645     }
1646     if (algName.compare(DSA_ASY_KEY_SPEC) == 0) {
1647         return GetDsaAsyKeySpec(env, arg, asyKeySpec);
1648     } else if (algName.compare(ECC_ASY_KEY_SPEC) == 0 || algName.compare(SM2_ASY_KEY_SPEC) == 0) {
1649         return GetEccAsyKeySpec(env, arg, asyKeySpec, algName);
1650     } else if (algName.compare(RSA_ASY_KEY_SPEC) == 0) {
1651         return GetRsaAsyKeySpec(env, arg, asyKeySpec);
1652     } else if (algName.compare(ED25519_ASY_KEY_SPEC) == 0 || algName.compare(X25519_ASY_KEY_SPEC) == 0) {
1653         return GetAlg25519AsyKeySpec(env, arg, asyKeySpec, algName);
1654     } else if (algName.compare(DH_ASY_KEY_SPEC) == 0) {
1655         return GetDh25519AsyKeySpec(env, arg, asyKeySpec);
1656     } else {
1657         LOGE("AlgName not support! [AlgName]: %s", algName.c_str());
1658         return false;
1659     }
1660 }
1661 
ConvertBlobToNapiValue(napi_env env,HcfBlob * blob)1662 napi_value ConvertBlobToNapiValue(napi_env env, HcfBlob *blob)
1663 {
1664     if (blob == nullptr || blob->data == nullptr || blob->len == 0) {
1665         LOGD("Invalid blob!");
1666         return NapiGetNull(env);
1667     }
1668     uint8_t *buffer = reinterpret_cast<uint8_t *>(HcfMalloc(blob->len, 0));
1669     if (buffer == nullptr) {
1670         LOGE("malloc uint8 array buffer failed!");
1671         return NapiGetNull(env);
1672     }
1673 
1674     if (memcpy_s(buffer, blob->len, blob->data, blob->len) != EOK) {
1675         LOGE("memcpy_s data to buffer failed!");
1676         HcfFree(buffer);
1677         return NapiGetNull(env);
1678     }
1679 
1680     napi_value outBuffer = nullptr;
1681     napi_status status = napi_create_external_arraybuffer(
1682         env, buffer, blob->len, [](napi_env env, void *data, void *hint) { HcfFree(data); }, nullptr, &outBuffer);
1683     if (status != napi_ok) {
1684         LOGE("create uint8 array buffer failed!");
1685         (void)memset_s(buffer, blob->len, 0, blob->len);
1686         HcfFree(buffer);
1687         return NapiGetNull(env);
1688     }
1689     buffer = nullptr;
1690 
1691     napi_value outData = nullptr;
1692     napi_create_typedarray(env, napi_uint8_array, blob->len, outBuffer, 0, &outData);
1693     napi_value dataBlob = nullptr;
1694     napi_create_object(env, &dataBlob);
1695     napi_set_named_property(env, dataBlob, CRYPTO_TAG_DATA.c_str(), outData);
1696 
1697     return dataBlob;
1698 }
1699 
ConvertDataBlobToNapiValue(napi_env env,HcfBlob * blob,napi_value * napiValue)1700 HcfResult ConvertDataBlobToNapiValue(napi_env env, HcfBlob *blob, napi_value *napiValue)
1701 {
1702     if (blob->data == nullptr || blob->len == 0) { // inner api, allow empty data
1703         *napiValue = NapiGetNull(env);
1704         return HCF_SUCCESS;
1705     }
1706 
1707     uint8_t *buffer = reinterpret_cast<uint8_t *>(HcfMalloc(blob->len, 0));
1708     if (buffer == nullptr) {
1709         LOGE("malloc uint8 array buffer failed!");
1710         return HCF_ERR_MALLOC;
1711     }
1712     (void)memcpy_s(buffer, blob->len, blob->data, blob->len);
1713 
1714     napi_value outBuffer = nullptr;
1715     napi_status status = napi_create_external_arraybuffer(
1716         env, buffer, blob->len, [](napi_env env, void *data, void *hint) { HcfFree(data); }, nullptr, &outBuffer);
1717     if (status != napi_ok) {
1718         LOGE("create napi uint8 array buffer failed!");
1719         HcfFree(buffer);
1720         return HCF_ERR_NAPI;
1721     }
1722 
1723     napi_value outData = nullptr;
1724     napi_create_typedarray(env, napi_uint8_array, blob->len, outBuffer, 0, &outData);
1725     napi_value dataBlob = nullptr;
1726     napi_create_object(env, &dataBlob);
1727     napi_set_named_property(env, dataBlob, CRYPTO_TAG_DATA.c_str(), outData);
1728     *napiValue = dataBlob;
1729     return HCF_SUCCESS;
1730 }
1731 
ConvertObjectBlobToNapiValue(napi_env env,HcfBlob * blob)1732 napi_value ConvertObjectBlobToNapiValue(napi_env env, HcfBlob *blob)
1733 {
1734     if (blob == nullptr || blob->data == nullptr || blob->len == 0) {
1735         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "Invalid blob!"));
1736         LOGE("Invalid blob!");
1737         return NapiGetNull(env);
1738     }
1739     uint8_t *buffer = reinterpret_cast<uint8_t *>(HcfMalloc(blob->len, 0));
1740     if (buffer == nullptr) {
1741         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc uint8 array buffer failed!"));
1742         LOGE("malloc uint8 array buffer failed!");
1743         return NapiGetNull(env);
1744     }
1745 
1746     if (memcpy_s(buffer, blob->len, blob->data, blob->len) != EOK) {
1747         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "memcpy_s data to buffer failed!"));
1748         LOGE("memcpy_s data to buffer failed!");
1749         HcfFree(buffer);
1750         return NapiGetNull(env);
1751     }
1752 
1753     napi_value outBuffer = nullptr;
1754     napi_status status = napi_create_external_arraybuffer(
1755         env, buffer, blob->len, [](napi_env env, void *data, void *hint) { HcfFree(data); }, nullptr, &outBuffer);
1756     if (status != napi_ok) {
1757         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "create uint8 array buffer failed!"));
1758         LOGE("create uint8 array buffer failed!");
1759         HcfFree(buffer);
1760         return NapiGetNull(env);
1761     }
1762     buffer = nullptr;
1763 
1764     napi_value outData = nullptr;
1765     napi_create_typedarray(env, napi_uint8_array, blob->len, outBuffer, 0, &outData);
1766     return outData;
1767 }
1768 
ConvertBigIntToNapiValue(napi_env env,HcfBigInteger * blob)1769 napi_value ConvertBigIntToNapiValue(napi_env env, HcfBigInteger *blob)
1770 {
1771     if (blob == nullptr || blob->data == nullptr || blob->len == 0) {
1772         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "Invalid blob!"));
1773         LOGE("Invalid blob!");
1774         return NapiGetNull(env);
1775     }
1776     size_t wordsCount = (blob->len / sizeof(uint64_t)) + ((blob->len % sizeof(uint64_t)) == 0 ? 0 : 1);
1777     uint64_t *words = reinterpret_cast<uint64_t *>(HcfMalloc(wordsCount * sizeof(uint64_t), 0));
1778     if (words == nullptr) {
1779         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc uint8 array buffer failed!"));
1780         LOGE("malloc uint8 array buffer failed!");
1781         return NapiGetNull(env);
1782     }
1783 
1784     size_t index = 0;
1785     for (size_t i = 0; index < wordsCount; i += sizeof(uint64_t), index++) {
1786         uint64_t tmp = 0;
1787         for (size_t j = 0; j < sizeof(uint64_t); j++) {
1788             if (i + j < blob->len) {
1789                 tmp += ((uint64_t)blob->data[i + j] << (sizeof(uint64_t) * j));
1790             }
1791         }
1792         words[index] = tmp;
1793     }
1794     napi_value bigInt = nullptr;
1795     napi_status status = napi_create_bigint_words(env, 0, wordsCount, words, &bigInt);
1796     if (status != napi_ok) {
1797         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "create bigint failed!"));
1798         LOGE("create bigint failed!");
1799         (void)memset_s(words, wordsCount * sizeof(uint64_t), 0, wordsCount * sizeof(uint64_t));
1800         HcfFree(words);
1801         return NapiGetNull(env);
1802     }
1803     if (bigInt == nullptr) {
1804         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "bigInt is null!"));
1805         LOGE("bigInt is null!");
1806     }
1807     (void)memset_s(words, wordsCount * sizeof(uint64_t), 0, wordsCount * sizeof(uint64_t));
1808     HcfFree(words);
1809     words = nullptr;
1810     return bigInt;
1811 }
1812 
GetStringFromJSParams(napi_env env,napi_value arg,string & returnStr)1813 bool GetStringFromJSParams(napi_env env, napi_value arg, string &returnStr)
1814 {
1815     napi_valuetype valueType;
1816     napi_typeof(env, arg, &valueType);
1817     if (valueType != napi_string) {
1818         LOGE("wrong argument type. expect string type.");
1819         return false;
1820     }
1821 
1822     size_t length = 0;
1823     if (napi_get_value_string_utf8(env, arg, nullptr, 0, &length) != napi_ok) {
1824         LOGE("can not get string length");
1825         return false;
1826     }
1827     returnStr.reserve(length + 1);
1828     returnStr.resize(length);
1829     if (napi_get_value_string_utf8(env, arg, returnStr.data(), (length + 1), &length) != napi_ok) {
1830         LOGE("can not get string value");
1831         return false;
1832     }
1833     return true;
1834 }
1835 
GetInt32FromJSParams(napi_env env,napi_value arg,int32_t & returnInt)1836 bool GetInt32FromJSParams(napi_env env, napi_value arg, int32_t &returnInt)
1837 {
1838     napi_valuetype valueType;
1839     napi_typeof(env, arg, &valueType);
1840     if (valueType != napi_number) {
1841         LOGE("wrong argument type. expect int type. [Type]: %d", valueType);
1842         return false;
1843     }
1844 
1845     if (napi_get_value_int32(env, arg, &returnInt) != napi_ok) {
1846         LOGE("can not get int value");
1847         return false;
1848     }
1849     return true;
1850 }
1851 
GetUint32FromJSParams(napi_env env,napi_value arg,uint32_t & returnInt)1852 bool GetUint32FromJSParams(napi_env env, napi_value arg, uint32_t &returnInt)
1853 {
1854     napi_valuetype valueType;
1855     napi_typeof(env, arg, &valueType);
1856     if (valueType != napi_number) {
1857         LOGE("wrong argument type. expect int type. [Type]: %d", valueType);
1858         return false;
1859     }
1860 
1861     if (napi_get_value_uint32(env, arg, &returnInt) != napi_ok) {
1862         LOGE("can not get int value");
1863         return false;
1864     }
1865     return true;
1866 }
1867 
GetUint64FromJSParams(napi_env env,napi_value arg,uint64_t & returnInt)1868 bool GetUint64FromJSParams(napi_env env, napi_value arg, uint64_t &returnInt)
1869 {
1870     napi_valuetype valueType;
1871     napi_typeof(env, arg, &valueType);
1872     if (valueType != napi_number) {
1873         LOGE("wrong argument type. expect int type. [Type]: %d", valueType);
1874         return false;
1875     }
1876     int64_t int64Value = 0;
1877     if (napi_get_value_int64(env, arg, &int64Value) != napi_ok) {
1878         LOGE("can not get int value");
1879         return false;
1880     }
1881     if (int64Value < 0) {
1882         LOGE("int64Value is less than 0");
1883         return false;
1884     }
1885     returnInt = static_cast<uint64_t>(int64Value);
1886     return true;
1887 }
1888 
GetCallbackFromJSParams(napi_env env,napi_value arg,napi_ref * returnCb)1889 bool GetCallbackFromJSParams(napi_env env, napi_value arg, napi_ref *returnCb)
1890 {
1891     napi_valuetype valueType = napi_undefined;
1892     napi_typeof(env, arg, &valueType);
1893     if (valueType != napi_function) {
1894         LOGE("wrong argument type. expect callback type. [Type]: %d", valueType);
1895         return false;
1896     }
1897 
1898     napi_create_reference(env, arg, 1, returnCb);
1899     return true;
1900 }
1901 
GetJsErrValueByErrCode(HcfResult errCode)1902 static uint32_t GetJsErrValueByErrCode(HcfResult errCode)
1903 {
1904     switch (errCode) {
1905         case HCF_INVALID_PARAMS:
1906             return JS_ERR_INVALID_PARAMS;
1907         case HCF_NOT_SUPPORT:
1908             return JS_ERR_NOT_SUPPORT;
1909         case HCF_ERR_MALLOC:
1910             return JS_ERR_OUT_OF_MEMORY;
1911         case HCF_ERR_NAPI:
1912             return JS_ERR_RUNTIME_ERROR;
1913         case HCF_ERR_CRYPTO_OPERATION:
1914             return JS_ERR_CRYPTO_OPERATION;
1915         default:
1916             return JS_ERR_DEFAULT_ERR;
1917     }
1918 }
1919 
GenerateBusinessError(napi_env env,HcfResult errCode,const char * errMsg)1920 napi_value GenerateBusinessError(napi_env env, HcfResult errCode, const char *errMsg)
1921 {
1922     napi_value businessError = nullptr;
1923 
1924     napi_value code = nullptr;
1925     napi_create_uint32(env, GetJsErrValueByErrCode(errCode), &code);
1926 
1927     napi_value msg = nullptr;
1928     napi_create_string_utf8(env, errMsg, NAPI_AUTO_LENGTH, &msg);
1929 
1930     napi_create_error(env, nullptr, msg, &businessError);
1931     napi_set_named_property(env, businessError, CRYPTO_TAG_ERR_CODE.c_str(), code);
1932 
1933     return businessError;
1934 }
1935 
CheckArgsCount(napi_env env,size_t argc,size_t expectedCount,bool isSync)1936 bool CheckArgsCount(napi_env env, size_t argc, size_t expectedCount, bool isSync)
1937 {
1938     if (isSync) {
1939         if (argc != expectedCount) {
1940             LOGE("invalid params count!");
1941             return false;
1942         }
1943     } else {
1944         if ((argc != expectedCount) && (argc != (expectedCount - ARGS_SIZE_ONE))) {
1945             LOGE("invalid params count!");
1946             return false;
1947         }
1948     }
1949     return true;
1950 }
1951 
isCallback(napi_env env,napi_value argv,size_t argc,size_t expectedArgc)1952 bool isCallback(napi_env env, napi_value argv, size_t argc, size_t expectedArgc)
1953 {
1954     if (argc == expectedArgc - 1) {
1955         return false;
1956     }
1957     napi_valuetype valueType = napi_undefined;
1958     napi_typeof(env, argv, &valueType);
1959     if (valueType == napi_undefined || valueType == napi_null) {
1960         return false;
1961     }
1962     return true;
1963 }
1964 
GetResourceName(napi_env env,const char * name)1965 napi_value GetResourceName(napi_env env, const char *name)
1966 {
1967     napi_value resourceName = nullptr;
1968     napi_create_string_utf8(env, name, NAPI_AUTO_LENGTH, &resourceName);
1969     return resourceName;
1970 }
1971 
BuildSetNamedProperty(napi_env env,HcfBigInteger * number,const char * name,napi_value * instance)1972 bool BuildSetNamedProperty(napi_env env, HcfBigInteger *number, const char *name, napi_value *instance)
1973 {
1974     napi_value value = ConvertBigIntToNapiValue(env, number);
1975     napi_status status = napi_set_named_property(env, *instance, name, value);
1976     if (status != napi_ok) {
1977         LOGE("create value failed!");
1978         return false;
1979     }
1980     return true;
1981 }
1982 }  // namespace CryptoFramework
1983 }  // namespace OHOS
1984