• 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     eccCommParamsSpec = nullptr;
353     return instance;
354 }
355 
JsConvertPoint(napi_env env,napi_callback_info info)356 napi_value NapiECCKeyUtil::JsConvertPoint(napi_env env, napi_callback_info info)
357 {
358     size_t expectedArgc = ARGS_SIZE_TWO;
359     size_t argc = ARGS_SIZE_TWO;
360     napi_value argv[ARGS_SIZE_TWO] = { nullptr };
361     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
362 
363     if (argc != expectedArgc) {
364         LOGE("The input args num is invalid.");
365         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid."));
366         return nullptr;
367     }
368 
369     std::string curveName;
370     if (!GetStringFromJSParams(env, argv[PARAM0], curveName)) {
371         LOGE("failed to get curveName.");
372         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get curveName."));
373         return nullptr;
374     }
375 
376     HcfBlob *pointBlob = GetBlobFromNapiUint8Arr(env, argv[PARAM1]);
377     if (pointBlob == nullptr) {
378         LOGE("failed to get point blob.");
379         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get point blob."));
380         return nullptr;
381     }
382 
383     HcfPoint point;
384     HcfResult ret = HcfConvertPoint(curveName.c_str(), pointBlob, &point);
385     if (ret != HCF_SUCCESS) {
386         LOGE("failed to convert point.");
387         HcfBlobDataFree(pointBlob);
388         HcfFree(pointBlob);
389         pointBlob = nullptr;
390         napi_throw(env, GenerateBusinessError(env, ret, "failed to convert point."));
391         return nullptr;
392     }
393     napi_value instance = ConvertEccPointToNapiValue(env, &point);
394     FreeEcPointMem(&point);
395     HcfBlobDataFree(pointBlob);
396     HcfFree(pointBlob);
397     pointBlob = nullptr;
398     return instance;
399 }
400 
JsGetEncodedPoint(napi_env env,napi_callback_info info)401 napi_value NapiECCKeyUtil::JsGetEncodedPoint(napi_env env, napi_callback_info info)
402 {
403     size_t expectedArgc = ARGS_SIZE_THREE;
404     size_t argc = ARGS_SIZE_THREE;
405     napi_value argv[ARGS_SIZE_THREE] = { nullptr };
406     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
407 
408     if (argc != expectedArgc) {
409         LOGE("The input args num is invalid.");
410         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid."));
411         return nullptr;
412     }
413 
414     std::string curveName;
415     if (!GetStringFromJSParams(env, argv[PARAM0], curveName)) {
416         LOGE("failed to get curveName.");
417         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get curveName."));
418         return nullptr;
419     }
420 
421     HcfPoint point;
422     if (!GetPointFromNapiValue(env, argv[PARAM1], &point)) {
423         LOGE("failed to get point.");
424         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get point."));
425         return nullptr;
426     }
427 
428     std::string format;
429     if (!GetStringFromJSParams(env, argv[PARAM2], format)) {
430         LOGE("failed to get format.");
431         FreeEcPointMem(&point);
432         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get format."));
433         return nullptr;
434     }
435 
436     HcfBlob returnBlob;
437     HcfResult ret = HcfGetEncodedPoint(curveName.c_str(), &point, format.c_str(), &returnBlob);
438     if (ret != HCF_SUCCESS) {
439         LOGE("fail to get point data.");
440         FreeEcPointMem(&point);
441         napi_throw(env, GenerateBusinessError(env, ret, "failed to get point data."));
442         return nullptr;
443     }
444     napi_value instance = ConvertObjectBlobToNapiValue(env, &returnBlob);
445     FreeEcPointMem(&point);
446     HcfBlobDataFree(&returnBlob);
447     return instance;
448 }
449 
ECCKeyUtilConstructor(napi_env env,napi_callback_info info)450 napi_value NapiECCKeyUtil::ECCKeyUtilConstructor(napi_env env, napi_callback_info info)
451 {
452     napi_value thisVar = nullptr;
453     size_t argc = ARGS_SIZE_ONE;
454     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
455     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
456     return thisVar;
457 }
458 
GenECCCommonParamSpec(napi_env env)459 napi_value NapiECCKeyUtil::GenECCCommonParamSpec(napi_env env)
460 {
461     napi_value cons = nullptr;
462     napi_property_descriptor clzDes[] = {
463         DECLARE_NAPI_STATIC_FUNCTION("genECCCommonParamsSpec", NapiECCKeyUtil::JsGenECCCommonParamsSpec),
464         DECLARE_NAPI_STATIC_FUNCTION("convertPoint", NapiECCKeyUtil::JsConvertPoint),
465         DECLARE_NAPI_STATIC_FUNCTION("getEncodedPoint", NapiECCKeyUtil::JsGetEncodedPoint),
466     };
467     NAPI_CALL(env, napi_define_class(env, "ECCKeyUtil", NAPI_AUTO_LENGTH, NapiECCKeyUtil::ECCKeyUtilConstructor,
468         nullptr, sizeof(clzDes) / sizeof(clzDes[0]), clzDes, &cons));
469     return cons;
470 }
471 
DefineNapiECCKeyUtilJSClass(napi_env env,napi_value exports)472 void NapiECCKeyUtil::DefineNapiECCKeyUtilJSClass(napi_env env, napi_value exports)
473 {
474     napi_set_named_property(env, exports, "ECCKeyUtil", NapiECCKeyUtil::GenECCCommonParamSpec(env));
475 }
476 } // CryptoFramework
477 } // OHOS
478