• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023-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_ecc_key_util.h"
17 #include "securec.h"
18 #include "detailed_ecc_key_params.h"
19 #include "log.h"
20 
21 #include "memory.h"
22 #include "napi_crypto_framework_defines.h"
23 #include "napi_utils.h"
24 #include "napi_key_pair.h"
25 #include "napi_pri_key.h"
26 #include "napi_pub_key.h"
27 #include "utils.h"
28 
29 namespace OHOS {
30 namespace CryptoFramework {
NapiECCKeyUtil()31 NapiECCKeyUtil::NapiECCKeyUtil() {}
32 
~NapiECCKeyUtil()33 NapiECCKeyUtil::~NapiECCKeyUtil() {}
34 
CheckEccCommonParamSpecBase(napi_env env,HcfEccCommParamsSpec * blob)35 static bool CheckEccCommonParamSpecBase(napi_env env, HcfEccCommParamsSpec *blob)
36 {
37     if (blob->a.data == nullptr || blob->a.len == 0) {
38         LOGE("Invalid blob a!");
39         return false;
40     }
41     if (blob->b.data == nullptr || blob->b.len == 0) {
42         LOGE("Invalid blob b!");
43         return false;
44     }
45     if (blob->n.data == nullptr || blob->n.len == 0) {
46         LOGE("Invalid blob n!");
47         return false;
48     }
49     return true;
50 }
51 
CheckEccCommonParamSpec(napi_env env,HcfEccCommParamsSpec * blob)52 static bool CheckEccCommonParamSpec(napi_env env, HcfEccCommParamsSpec *blob)
53 {
54     if (blob == nullptr) {
55         LOGE("Invalid blob!");
56         return false;
57     }
58     if (!CheckEccCommonParamSpecBase(env, blob)) {
59         LOGE("Invalid blob ecc commonParamSpec base!");
60         return false;
61     }
62     if (blob->base.algName == nullptr) {
63         LOGE("Invalid blob algName!");
64         return false;
65     }
66     if (blob->field == nullptr) {
67         LOGE("Invalid blob field!");
68         return false;
69     }
70     if (blob->field->fieldType == nullptr) {
71         LOGE("Invalid blob fieldType!");
72         return false;
73     }
74     if (blob->g.x.data == nullptr || blob->g.x.len == 0) {
75         LOGE("Invalid blob point x!");
76         return false;
77     }
78     if (blob->g.y.data == nullptr || blob->g.y.len == 0) {
79         LOGE("Invalid blob point y!");
80         return false;
81     }
82     HcfECFieldFp *tmpField = reinterpret_cast<HcfECFieldFp *>(blob->field);
83     if (tmpField->p.data == nullptr || tmpField->p.len == 0) {
84         LOGE("Invalid blob p!");
85         return false;
86     }
87     return true;
88 }
89 
ConvertEccCommonParamFieldFpToNapiValue(napi_env env,HcfEccCommParamsSpec * blob)90 static napi_value ConvertEccCommonParamFieldFpToNapiValue(napi_env env, HcfEccCommParamsSpec *blob)
91 {
92     napi_value fieldFp;
93     napi_value fieldType;
94     napi_status status = napi_create_object(env, &fieldFp);
95     if (status != napi_ok) {
96         LOGE("create fieldFp failed!");
97         return NapiGetNull(env);
98     }
99     size_t fieldTypeLength = HcfStrlen(blob->field->fieldType);
100     if (!fieldTypeLength) {
101         LOGE("fieldType is empty!");
102         return NapiGetNull(env);
103     }
104     status = napi_create_string_utf8(env, blob->field->fieldType, fieldTypeLength, &fieldType);
105     if (status != napi_ok) {
106         LOGE("create object failed!");
107         return NapiGetNull(env);
108     }
109     status = napi_set_named_property(env, fieldFp, "fieldType", fieldType);
110     if (status != napi_ok) {
111         LOGE("create object failed!");
112         return NapiGetNull(env);
113     }
114     HcfECFieldFp *tmpField = reinterpret_cast<HcfECFieldFp *>(blob->field);
115     napi_value p = ConvertBigIntToNapiValue(env, &(tmpField->p));
116     if (p == nullptr) {
117         LOGE("p is null!");
118         return NapiGetNull(env);
119     }
120     status = napi_set_named_property(env, fieldFp, "p", p);
121     if (status != napi_ok) {
122         LOGE("create object failed!");
123         return NapiGetNull(env);
124     }
125     return fieldFp;
126 }
127 
IsNapiNull(napi_env env,napi_value value)128 static bool IsNapiNull(napi_env env, napi_value value)
129 {
130     napi_valuetype valueType;
131     napi_typeof(env, value, &valueType);
132     return (valueType == napi_null);
133 }
134 
ConvertEccPointToNapiValue(napi_env env,HcfPoint * p)135 static napi_value ConvertEccPointToNapiValue(napi_env env, HcfPoint *p)
136 {
137     if (p == nullptr) {
138         LOGE("Invalid point data!");
139         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "Invalid point data!"));
140         return nullptr;
141     }
142 
143     napi_value point;
144     napi_status status = napi_create_object(env, &point);
145     if (status != napi_ok) {
146         LOGE("create object failed!");
147         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create object failed!"));
148         return nullptr;
149     }
150 
151     napi_value x = ConvertBigIntToNapiValue(env, &(p->x));
152     if (x == nullptr || IsNapiNull(env, x)) {
153         LOGE("Failed to convert x to NapiValue!");
154         return nullptr;
155     }
156 
157     napi_value y = ConvertBigIntToNapiValue(env, &(p->y));
158     if (y == nullptr || IsNapiNull(env, y)) {
159         LOGE("Failed to convert y to NapiValue!");
160         return nullptr;
161     }
162 
163     status = napi_set_named_property(env, point, "x", x);
164     if (status != napi_ok) {
165         LOGE("set x property failed!");
166         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "set x property failed!"));
167         return nullptr;
168     }
169 
170     status = napi_set_named_property(env, point, "y", y);
171     if (status != napi_ok) {
172         LOGE("set y property failed!");
173         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "set y property failed!"));
174         return nullptr;
175     }
176 
177     return point;
178 }
179 
ConvertEccCommonParamPointToNapiValue(napi_env env,HcfEccCommParamsSpec * blob)180 static napi_value ConvertEccCommonParamPointToNapiValue(napi_env env, HcfEccCommParamsSpec *blob)
181 {
182     napi_value point;
183     napi_status status = napi_create_object(env, &point);
184     if (status != napi_ok) {
185         LOGE("create object failed!");
186         return NapiGetNull(env);
187     }
188     napi_value x = ConvertBigIntToNapiValue(env, &(blob->g.x));
189     if (x == nullptr) {
190         LOGE("x is null!");
191         return NapiGetNull(env);
192     }
193 
194     napi_value y = ConvertBigIntToNapiValue(env, &(blob->g.y));
195     if (y == nullptr) {
196         LOGE("y is null!");
197         return NapiGetNull(env);
198     }
199     status = napi_set_named_property(env, point, "x", x);
200     if (status != napi_ok) {
201         LOGE("create object failed!");
202         return NapiGetNull(env);
203     }
204     status = napi_set_named_property(env, point, "y", y);
205     if (status != napi_ok) {
206         LOGE("create object failed!");
207         return NapiGetNull(env);
208     }
209     return point;
210 }
211 
BuildIntancePartertoNapiValueSon(napi_env env,napi_status status,HcfEccCommParamsSpec * blob,napi_value * instance)212 static bool BuildIntancePartertoNapiValueSon(napi_env env, napi_status status, HcfEccCommParamsSpec *blob,
213     napi_value *instance)
214 {
215     if (!BuildSetNamedProperty(env, &(blob->a), "a", instance)) {
216         LOGE("build setNamedProperty a failed!");
217         return false;
218     }
219     if (!BuildSetNamedProperty(env, &(blob->b), "b", instance)) {
220         LOGE("build setNamedProperty b failed!");
221         return false;
222     }
223     if (!BuildSetNamedProperty(env, &(blob->n), "n", instance)) {
224         LOGE("build setNamedProperty n failed!");
225         return false;
226     }
227     napi_value h;
228     status = napi_create_int32(env, blob->h, &h);
229     if (status != napi_ok) {
230         LOGE("create h uint32 failed!");
231         return false;
232     }
233     status = napi_set_named_property(env, *instance, "h", h);
234     if (status != napi_ok) {
235         LOGE("create h uint32 failed!");
236         return false;
237     }
238     return true;
239 }
240 
BuildInstanceParterToNapiValue(napi_env env,HcfEccCommParamsSpec * blob,napi_value * instance)241 static bool BuildInstanceParterToNapiValue(napi_env env, HcfEccCommParamsSpec *blob, napi_value *instance)
242 {
243     napi_value algName;
244     size_t algNameLength = HcfStrlen(blob->base.algName);
245     if (!algNameLength) {
246         LOGE("algName is empty!");
247         return false;
248     }
249     napi_status status = napi_create_string_utf8(env, blob->base.algName, algNameLength, &algName);
250     if (status != napi_ok) {
251         LOGE("create algName failed!");
252         return false;
253     }
254     napi_value specType;
255     status = napi_create_uint32(env, blob->base.specType, &specType);
256     if (status != napi_ok) {
257         LOGE("create uint32 failed!");
258         return false;
259     }
260     status = napi_set_named_property(env, *instance, "algName", algName);
261     if (status != napi_ok) {
262         LOGE("create set algName failed!");
263         return false;
264     }
265     status = napi_set_named_property(env, *instance, "specType", specType);
266     if (status != napi_ok) {
267         LOGE("create set specType failed!");
268         return false;
269     }
270     if (!BuildIntancePartertoNapiValueSon(env, status, blob, instance)) {
271         LOGE("create intance parter napi value failed!");
272         return false;
273     }
274     return true;
275 }
276 
ConvertEccCommParamsSpecToNapiValue(napi_env env,HcfEccCommParamsSpec * blob)277 static napi_value ConvertEccCommParamsSpecToNapiValue(napi_env env, HcfEccCommParamsSpec *blob)
278 {
279     if (!CheckEccCommonParamSpec(env, blob)) {
280         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "Invalid blob!"));
281         LOGE("Invalid blob!");
282         return NapiGetNull(env);
283     }
284     napi_value instance;
285     napi_status status = napi_create_object(env, &instance);
286     if (status != napi_ok) {
287         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "create object failed!"));
288         LOGE("create object failed!");
289         return NapiGetNull(env);
290     }
291     napi_value point = ConvertEccCommonParamPointToNapiValue(env, blob);
292     if (point == NapiGetNull(env)) {
293         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "covert commonParam failed!"));
294         LOGE("Covert commonParam failed!");
295         return NapiGetNull(env);
296     }
297     napi_value field = ConvertEccCommonParamFieldFpToNapiValue(env, blob);
298     if (field == NapiGetNull(env)) {
299         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "covert commonParam fieldFp failed!"));
300         LOGE("Covert commonParam fieldFp failed!");
301         return NapiGetNull(env);
302     }
303     if (!BuildInstanceParterToNapiValue(env, blob, &instance)) {
304         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build object failed!"));
305         LOGE("Build object failed!");
306         return NapiGetNull(env);
307     }
308     status = napi_set_named_property(env, instance, "field", field);
309     if (status != napi_ok) {
310         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "set fieldFp failed!"));
311         LOGE("set fieldFp failed!");
312         return NapiGetNull(env);
313     }
314     status = napi_set_named_property(env, instance, "g", point);
315     if (status != napi_ok) {
316         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "set g failed!"));
317         LOGE("set g failed!");
318         return NapiGetNull(env);
319     }
320     return instance;
321 }
322 
JsGenECCCommonParamsSpec(napi_env env,napi_callback_info info)323 napi_value NapiECCKeyUtil::JsGenECCCommonParamsSpec(napi_env env, napi_callback_info info)
324 {
325     size_t expectedArgc = ARGS_SIZE_ONE;
326     size_t argc = ARGS_SIZE_ONE;
327     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
328     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
329 
330     if (argc != expectedArgc) {
331         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid."));
332         LOGE("The input args num is invalid.");
333         return nullptr;
334     }
335 
336     std::string algName;
337     if (!GetStringFromJSParams(env, argv[0], algName)) {
338         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get algoName."));
339         LOGE("failed to get algoName.");
340         return NapiGetNull(env);
341     }
342 
343     HcfEccCommParamsSpec *eccCommParamsSpec = nullptr;
344     if (HcfEccKeyUtilCreate(algName.c_str(), &eccCommParamsSpec) != HCF_SUCCESS) {
345         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "create c generator fail."));
346         LOGE("create c generator fail.");
347         return NapiGetNull(env);
348     }
349     napi_value instance = ConvertEccCommParamsSpecToNapiValue(env, eccCommParamsSpec);
350     FreeEccCommParamsSpec(eccCommParamsSpec);
351     HcfFree(eccCommParamsSpec);
352     return instance;
353 }
354 
JsConvertPoint(napi_env env,napi_callback_info info)355 napi_value NapiECCKeyUtil::JsConvertPoint(napi_env env, napi_callback_info info)
356 {
357     size_t expectedArgc = ARGS_SIZE_TWO;
358     size_t argc = ARGS_SIZE_TWO;
359     napi_value argv[ARGS_SIZE_TWO] = { nullptr };
360     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
361 
362     if (argc != expectedArgc) {
363         LOGE("The input args num is invalid.");
364         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid."));
365         return nullptr;
366     }
367 
368     std::string curveName;
369     if (!GetStringFromJSParams(env, argv[PARAM0], curveName)) {
370         LOGE("failed to get curveName.");
371         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get curveName."));
372         return nullptr;
373     }
374 
375     HcfBlob *pointBlob = GetBlobFromNapiUint8Arr(env, argv[PARAM1]);
376     if (pointBlob == nullptr) {
377         LOGE("failed to get point blob.");
378         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get point blob."));
379         return nullptr;
380     }
381 
382     HcfPoint point;
383     HcfResult ret = HcfConvertPoint(curveName.c_str(), pointBlob, &point);
384     if (ret != HCF_SUCCESS) {
385         LOGE("failed to convert point.");
386         HcfBlobDataFree(pointBlob);
387         HcfFree(pointBlob);
388         napi_throw(env, GenerateBusinessError(env, ret, "failed to convert point."));
389         return nullptr;
390     }
391     napi_value instance = ConvertEccPointToNapiValue(env, &point);
392     FreeEcPointMem(&point);
393     HcfBlobDataFree(pointBlob);
394     HcfFree(pointBlob);
395     return instance;
396 }
397 
JsGetEncodedPoint(napi_env env,napi_callback_info info)398 napi_value NapiECCKeyUtil::JsGetEncodedPoint(napi_env env, napi_callback_info info)
399 {
400     size_t expectedArgc = ARGS_SIZE_THREE;
401     size_t argc = ARGS_SIZE_THREE;
402     napi_value argv[ARGS_SIZE_THREE] = { nullptr };
403     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
404 
405     if (argc != expectedArgc) {
406         LOGE("The input args num is invalid.");
407         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid."));
408         return nullptr;
409     }
410 
411     std::string curveName;
412     if (!GetStringFromJSParams(env, argv[PARAM0], curveName)) {
413         LOGE("failed to get curveName.");
414         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get curveName."));
415         return nullptr;
416     }
417 
418     HcfPoint point;
419     if (!GetPointFromNapiValue(env, argv[PARAM1], &point)) {
420         LOGE("failed to get point.");
421         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get point."));
422         return nullptr;
423     }
424 
425     std::string format;
426     if (!GetStringFromJSParams(env, argv[PARAM2], format)) {
427         LOGE("failed to get format.");
428         FreeEcPointMem(&point);
429         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get format."));
430         return nullptr;
431     }
432 
433     HcfBlob returnBlob;
434     HcfResult ret = HcfGetEncodedPoint(curveName.c_str(), &point, format.c_str(), &returnBlob);
435     if (ret != HCF_SUCCESS) {
436         LOGE("fail to get point data.");
437         FreeEcPointMem(&point);
438         napi_throw(env, GenerateBusinessError(env, ret, "failed to get point data."));
439         return nullptr;
440     }
441     napi_value instance = ConvertObjectBlobToNapiValue(env, &returnBlob);
442     FreeEcPointMem(&point);
443     HcfBlobDataFree(&returnBlob);
444     return instance;
445 }
446 
ECCKeyUtilConstructor(napi_env env,napi_callback_info info)447 napi_value NapiECCKeyUtil::ECCKeyUtilConstructor(napi_env env, napi_callback_info info)
448 {
449     napi_value thisVar = nullptr;
450     size_t argc = ARGS_SIZE_ONE;
451     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
452     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
453     return thisVar;
454 }
455 
GenECCCommonParamSpec(napi_env env)456 napi_value NapiECCKeyUtil::GenECCCommonParamSpec(napi_env env)
457 {
458     napi_value cons = nullptr;
459     napi_property_descriptor clzDes[] = {
460         DECLARE_NAPI_STATIC_FUNCTION("genECCCommonParamsSpec", NapiECCKeyUtil::JsGenECCCommonParamsSpec),
461         DECLARE_NAPI_STATIC_FUNCTION("convertPoint", NapiECCKeyUtil::JsConvertPoint),
462         DECLARE_NAPI_STATIC_FUNCTION("getEncodedPoint", NapiECCKeyUtil::JsGetEncodedPoint),
463     };
464     NAPI_CALL(env, napi_define_class(env, "ECCKeyUtil", NAPI_AUTO_LENGTH, NapiECCKeyUtil::ECCKeyUtilConstructor,
465         nullptr, sizeof(clzDes) / sizeof(clzDes[0]), clzDes, &cons));
466     return cons;
467 }
468 
DefineNapiECCKeyUtilJSClass(napi_env env,napi_value exports)469 void NapiECCKeyUtil::DefineNapiECCKeyUtilJSClass(napi_env env, napi_value exports)
470 {
471     napi_set_named_property(env, exports, "ECCKeyUtil", NapiECCKeyUtil::GenECCCommonParamSpec(env));
472 }
473 } // CryptoFramework
474 } // OHOS
475