• 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 "ecc_common_param_spec_generator_openssl.h"
17 #include "securec.h"
18 
19 #include "ecc_openssl_common.h"
20 #include "ecc_openssl_common_param_spec.h"
21 #include "log.h"
22 #include "memory.h"
23 #include "openssl_adapter.h"
24 #include "openssl_class.h"
25 #include "openssl_common.h"
26 #include "utils.h"
27 
BuildEcPoint(const EC_GROUP * ecGroup)28 static EC_POINT *BuildEcPoint(const EC_GROUP *ecGroup)
29 {
30     EC_POINT *point = OpensslEcPointNew(ecGroup);
31     if (point == NULL) {
32         LOGE("new ec point failed.");
33         return NULL;
34     }
35     const EC_POINT *tmpPoint = OpensslEcGroupGet0Generator(ecGroup);
36     if (tmpPoint == NULL) {
37         LOGE("Get ec generator failed.");
38         OpensslEcPointFree(point);
39         return NULL;
40     }
41     if (!OpensslEcPointCopy(point, tmpPoint)) {
42         LOGE("Ec point copy failed.");
43         OpensslEcPointFree(point);
44         return NULL;
45     }
46 
47     return point;
48 }
49 
BuildCommonParamPart(const EC_GROUP * ecGroup,HcfEccCommParamsSpecSpi * returnCommonParamSpec)50 static HcfResult BuildCommonParamPart(const EC_GROUP *ecGroup, HcfEccCommParamsSpecSpi *returnCommonParamSpec)
51 {
52     EC_POINT *point = NULL;
53     point = BuildEcPoint(ecGroup);
54     if (point == NULL) {
55         LOGE("Build ec point failed.");
56         return HCF_ERR_MALLOC;
57     }
58     BIGNUM *x = OpensslBnNew();
59     if (x == NULL) {
60         LOGE("New x failed.");
61         OpensslEcPointFree(point);
62         return HCF_ERR_MALLOC;
63     }
64     BIGNUM *y = OpensslBnNew();
65     if (y == NULL) {
66         LOGE("New y failed.");
67         OpensslBnFree(x);
68         OpensslEcPointFree(point);
69         return HCF_ERR_MALLOC;
70     }
71     HcfResult ret = HCF_SUCCESS;
72     do {
73         if (!OpensslEcPointGetAffineCoordinatesGfp(ecGroup, point, x, y, NULL)) {
74             LOGE("EC_POINT_get_affine_coordinates_GFp failed.");
75             ret = HCF_ERR_CRYPTO_OPERATION;
76             break;
77         }
78         if (BigNumToBigInteger(x, &(returnCommonParamSpec->paramsSpec.g.x)) != HCF_SUCCESS) {
79             LOGE("Build commonParamSpec x failed.");
80             ret = HCF_ERR_CRYPTO_OPERATION;
81             break;
82         }
83         if (BigNumToBigInteger(y, &(returnCommonParamSpec->paramsSpec.g.y)) != HCF_SUCCESS) {
84             LOGE("Build commonParamSpec y failed.");
85             ret = HCF_ERR_CRYPTO_OPERATION;
86             break;
87         }
88     } while (0);
89     OpensslBnFree(x);
90     OpensslBnFree(y);
91     OpensslEcPointFree(point);
92     return ret;
93 }
94 
BuildCommonParamGFp(const EC_GROUP * ecGroup,HcfEccCommParamsSpecSpi * returnCommonParamSpec)95 static HcfResult BuildCommonParamGFp(const EC_GROUP *ecGroup, HcfEccCommParamsSpecSpi *returnCommonParamSpec)
96 {
97     BIGNUM *p = OpensslBnNew();
98     if (p == NULL) {
99         LOGE("New p failed.");
100         return HCF_ERR_MALLOC;
101     }
102     BIGNUM *a = OpensslBnNew();
103     if (a == NULL) {
104         LOGE("New a failed.");
105         OpensslBnFree(p);
106         return HCF_ERR_MALLOC;
107     }
108     BIGNUM *b = OpensslBnNew();
109     if (b == NULL) {
110         LOGE("New b failed.");
111         OpensslBnFree(p);
112         OpensslBnFree(a);
113         return HCF_ERR_MALLOC;
114     }
115     if (!OpensslEcGroupGetCurveGfp(ecGroup, p, a, b, NULL)) {
116         LOGE("EC_GROUP_get_curve_GFp failed.");
117         OpensslBnFree(p);
118         OpensslBnFree(a);
119         OpensslBnFree(b);
120         return HCF_ERR_CRYPTO_OPERATION;
121     }
122     HcfResult ret = HCF_SUCCESS;
123 
124     do {
125         if (BigNumToBigInteger(a, &(returnCommonParamSpec->paramsSpec.a)) != HCF_SUCCESS) {
126             LOGE("Build commonParamSpec a failed.");
127             ret = HCF_ERR_CRYPTO_OPERATION;
128             break;
129         }
130         if (BigNumToBigInteger(b, &(returnCommonParamSpec->paramsSpec.b)) != HCF_SUCCESS) {
131             LOGE("Build commonParamSpec b failed.");
132             ret = HCF_ERR_CRYPTO_OPERATION;
133             break;
134         }
135         HcfECFieldFp *tmpField = (HcfECFieldFp *)(returnCommonParamSpec->paramsSpec.field);
136         if (BigNumToBigInteger(p, &(tmpField->p)) != HCF_SUCCESS) {
137             LOGE("Build commonParamSpec p failed.");
138             ret = HCF_ERR_CRYPTO_OPERATION;
139             break;
140         }
141     } while (0);
142 
143     OpensslBnFree(p);
144     OpensslBnFree(a);
145     OpensslBnFree(b);
146     return ret;
147 }
148 
BuildCommonParam(const EC_GROUP * ecGroup,HcfEccCommParamsSpecSpi * returnCommonParamSpec)149 static HcfResult BuildCommonParam(const EC_GROUP *ecGroup, HcfEccCommParamsSpecSpi *returnCommonParamSpec)
150 {
151     if (BuildCommonParamPart(ecGroup, returnCommonParamSpec)!= HCF_SUCCESS) {
152         LOGE("BuildCommonParamPartOne failed.");
153         return HCF_ERR_CRYPTO_OPERATION;
154     }
155     if (BuildCommonParamGFp(ecGroup, returnCommonParamSpec)!= HCF_SUCCESS) {
156         LOGE("BuildCommonParamGFp failed.");
157         return HCF_ERR_CRYPTO_OPERATION;
158     }
159     if (GetOrder(ecGroup, &(returnCommonParamSpec->paramsSpec.n)) != HCF_SUCCESS) {
160         LOGE("Failed to get curve order data.");
161         return HCF_ERR_CRYPTO_OPERATION;
162     }
163 
164     if (GetCofactor(ecGroup, &(returnCommonParamSpec->paramsSpec.h)) != HCF_SUCCESS) {
165         LOGE("Failed to get curve cofactor data.");
166         return HCF_ERR_CRYPTO_OPERATION;
167     }
168     return HCF_SUCCESS;
169 }
170 
BuildEccCommonParamObject(void)171 static HcfEccCommParamsSpecSpi *BuildEccCommonParamObject(void)
172 {
173     HcfEccCommParamsSpecSpi *spi = (HcfEccCommParamsSpecSpi*)HcfMalloc(sizeof(HcfEccCommParamsSpecSpi), 0);
174     if (spi == NULL) {
175         LOGE("failed to build ecc commonParam object.");
176         return NULL;
177     }
178     spi->paramsSpec.field = (HcfECField *)HcfMalloc(sizeof(HcfECFieldFp), 0);
179     if (spi->paramsSpec.field == NULL) {
180         LOGE("field malloc failed.");
181         HcfFree(spi);
182         return NULL;
183     }
184     char *fieldType = "Fp";
185     size_t srcFieldTypeLen = HcfStrlen(fieldType);
186     if (srcFieldTypeLen == 0) {
187         LOGE("fieldType is empty!");
188         HcfFree(spi->paramsSpec.field);
189         HcfFree(spi);
190         return NULL;
191     }
192     spi->paramsSpec.field->fieldType = (char *)HcfMalloc(srcFieldTypeLen + 1, 0);
193     if (spi->paramsSpec.field->fieldType == NULL) {
194         LOGE("fieldType malloc failed.");
195         HcfFree(spi->paramsSpec.field);
196         HcfFree(spi);
197         return NULL;
198     }
199 
200     if (memcpy_s(spi->paramsSpec.field->fieldType, srcFieldTypeLen, fieldType, srcFieldTypeLen) != EOK) {
201         LOGE("memcpy fieldType failed.");
202         HcfFree(spi->paramsSpec.field->fieldType);
203         HcfFree(spi->paramsSpec.field);
204         HcfFree(spi);
205         return NULL;
206     }
207     return spi;
208 }
209 
FreeEccCommParamObject(HcfEccCommParamsSpecSpi * spec)210 static void FreeEccCommParamObject(HcfEccCommParamsSpecSpi *spec)
211 {
212     if (spec == NULL) {
213         LOGE("Invalid input parameter.");
214         return;
215     }
216     HcfFree(spec->paramsSpec.base.algName);
217     spec->paramsSpec.base.algName = NULL;
218     if (spec->paramsSpec.field != NULL) {
219         HcfECFieldFp *tmp = (HcfECFieldFp *)spec->paramsSpec.field;
220         HcfFree(tmp->p.data);
221         tmp->p.data = NULL;
222         HcfFree(spec->paramsSpec.field->fieldType);
223         spec->paramsSpec.field->fieldType = NULL;
224         HcfFree(spec->paramsSpec.field);
225         spec->paramsSpec.field = NULL;
226     }
227     HcfFree(spec->paramsSpec.a.data);
228     spec->paramsSpec.a.data = NULL;
229     HcfFree(spec->paramsSpec.b.data);
230     spec->paramsSpec.b.data = NULL;
231     HcfFree(spec->paramsSpec.n.data);
232     spec->paramsSpec.n.data = NULL;
233     HcfFree(spec->paramsSpec.g.x.data);
234     spec->paramsSpec.g.x.data = NULL;
235     HcfFree(spec->paramsSpec.g.y.data);
236     spec->paramsSpec.g.y.data = NULL;
237     HcfFree(spec);
238 }
239 
HcfECCCommonParamSpecCreate(HcfAsyKeyGenParams * params,HcfEccCommParamsSpecSpi ** returnCommonParamSpec)240 HcfResult HcfECCCommonParamSpecCreate(HcfAsyKeyGenParams *params, HcfEccCommParamsSpecSpi **returnCommonParamSpec)
241 {
242     if ((params == NULL) || (returnCommonParamSpec == NULL)) {
243         LOGE("Invalid input parameter.");
244         return HCF_INVALID_PARAMS;
245     }
246     int32_t curveId = 0;
247     if (params->bits != 0) {
248         if (GetOpensslCurveId(params->bits, &curveId) != HCF_SUCCESS) {
249             LOGE("Get curveId parameter failed.");
250             return HCF_INVALID_PARAMS;
251         }
252     }
253     EC_GROUP *ecGroup = OpensslEcGroupNewByCurveName(curveId);
254     if (ecGroup == NULL) {
255         LOGE("Create ecGroup failed.");
256         return HCF_ERR_CRYPTO_OPERATION;
257     }
258     HcfEccCommParamsSpecSpi *object = BuildEccCommonParamObject();
259     if (object == NULL) {
260         LOGE("Build ecc common params object failed.");
261         OpensslEcGroupFree(ecGroup);
262         return HCF_ERR_MALLOC;
263     }
264     object->paramsSpec.base.specType = HCF_COMMON_PARAMS_SPEC;
265     if (GetAlgNameByBits(params->bits, &(object->paramsSpec.base.algName)) != HCF_SUCCESS) {
266         LOGE("Get algName parameter by bits failed.");
267         FreeEccCommParamObject(object);
268         object = NULL;
269         OpensslEcGroupFree(ecGroup);
270         return HCF_INVALID_PARAMS;
271     }
272     if (BuildCommonParam(ecGroup, object)!= HCF_SUCCESS) {
273         LOGE("Get common params failed.");
274         FreeEccCommParamObject(object);
275         object = NULL;
276         OpensslEcGroupFree(ecGroup);
277         return HCF_ERR_CRYPTO_OPERATION;
278     }
279     *returnCommonParamSpec = object;
280     OpensslEcGroupFree(ecGroup);
281     return HCF_SUCCESS;
282 }
283 
InitEccPoint(const int32_t curveNameValue,EC_GROUP ** ecGroup,EC_POINT ** ecPoint,BIGNUM ** x,BIGNUM ** y)284 static HcfResult InitEccPoint(const int32_t curveNameValue, EC_GROUP **ecGroup,
285                               EC_POINT **ecPoint, BIGNUM **x, BIGNUM **y)
286 {
287     int32_t nid = 0;
288     if (GetNidByCurveNameValue(curveNameValue, &nid) != HCF_SUCCESS) {
289         LOGE("Failed to get curveNameValue.");
290         return HCF_INVALID_PARAMS;
291     }
292     *ecGroup = OpensslEcGroupNewByCurveName(nid);
293     if (*ecGroup == NULL) {
294         LOGE("Failed to create EC group with nid %d.", nid);
295         return HCF_ERR_CRYPTO_OPERATION;
296     }
297     *ecPoint = OpensslEcPointNew(*ecGroup);
298     if (*ecPoint == NULL) {
299         LOGE("Failed to allocate memory for EC_POINT.");
300         OpensslEcGroupFree(*ecGroup);
301         *ecGroup = NULL;
302         return HCF_ERR_CRYPTO_OPERATION;
303     }
304     if (x != NULL) {
305         *x = OpensslBnNew();
306         if (*x == NULL) {
307             LOGE("Failed to allocate memory for BIGNUM x.");
308             OpensslEcGroupFree(*ecGroup);
309             *ecGroup = NULL;
310             OpensslEcPointFree(*ecPoint);
311             *ecPoint = NULL;
312             return HCF_ERR_CRYPTO_OPERATION;
313         }
314     }
315     if (y != NULL) {
316         *y = OpensslBnNew();
317         if (*y == NULL) {
318             LOGE("Failed to allocate memory for BIGNUM y.");
319             OpensslBnFree(*x);
320             *x = NULL;
321             OpensslEcGroupFree(*ecGroup);
322             *ecGroup = NULL;
323             OpensslEcPointFree(*ecPoint);
324             *ecPoint = NULL;
325             return HCF_ERR_CRYPTO_OPERATION;
326         }
327     }
328     return HCF_SUCCESS;
329 }
330 
FreeHcfBigInteger(HcfBigInteger * bigInt)331 static void FreeHcfBigInteger(HcfBigInteger *bigInt)
332 {
333     HcfFree(bigInt->data);
334     bigInt->data = NULL;
335     bigInt->len = 0;
336 }
337 
ConvertBigNumToEccPoint(const BIGNUM * x,const BIGNUM * y,HcfBigInteger * bigIntX,HcfBigInteger * bigIntY)338 static HcfResult ConvertBigNumToEccPoint(const BIGNUM *x, const BIGNUM *y,
339                                          HcfBigInteger *bigIntX, HcfBigInteger *bigIntY)
340 {
341     HcfResult ret = BigNumToBigInteger(x, bigIntX);
342     if (ret != HCF_SUCCESS) {
343         LOGE("Failed to convert XBIGNUM to HcfBigInteger.");
344         return ret;
345     }
346     ret = BigNumToBigInteger(y, bigIntY);
347     if (ret != HCF_SUCCESS) {
348         LOGE("Failed to convert YBIGNUM to HcfBigInteger.");
349         FreeHcfBigInteger(bigIntX);
350         return ret;
351     }
352     return HCF_SUCCESS;
353 }
354 
GetECCPointEncoded(const int32_t formatValue,EC_GROUP * ecGroup,EC_POINT * ecPoint,HcfBlob * returnBlob)355 static HcfResult GetECCPointEncoded(const int32_t formatValue, EC_GROUP *ecGroup,
356                                     EC_POINT *ecPoint, HcfBlob *returnBlob)
357 {
358     int32_t formatType = 0;
359     if (GetFormatTypeByFormatValue(formatValue, &formatType) != HCF_SUCCESS) {
360         LOGE("Failed to get formatType.");
361         return HCF_INVALID_PARAMS;
362     }
363 
364     size_t returnDataLen = EC_POINT_point2oct(ecGroup, ecPoint, formatType, NULL, 0, NULL);
365     if (returnDataLen == 0) {
366         LOGE("Failed to get encoded point length.");
367         HcfPrintOpensslError();
368         return HCF_ERR_CRYPTO_OPERATION;
369     }
370 
371     uint8_t *returnData = (uint8_t *)HcfMalloc(returnDataLen, 0);
372     if (returnData == NULL) {
373         LOGE("Failed to allocate memory for encoded point data.");
374         return HCF_ERR_MALLOC;
375     }
376     size_t result = EC_POINT_point2oct(ecGroup, ecPoint, formatType, returnData, returnDataLen, NULL);
377     if (result != returnDataLen) {
378         LOGE("Failed to get ECC point encoding.");
379         HcfPrintOpensslError();
380         HcfFree(returnData);
381         return HCF_ERR_CRYPTO_OPERATION;
382     }
383     returnBlob->data = returnData;
384     returnBlob->len = returnDataLen;
385     return HCF_SUCCESS;
386 }
387 
HcfEngineConvertPoint(const int32_t curveNameValue,HcfBlob * pointBlob,HcfPoint * returnPoint)388 HcfResult HcfEngineConvertPoint(const int32_t curveNameValue, HcfBlob *pointBlob, HcfPoint *returnPoint)
389 {
390     if ((curveNameValue == 0) || !HcfIsBlobValid(pointBlob) || (returnPoint == NULL)) {
391         LOGE("Invalid input parameter.");
392         return HCF_INVALID_PARAMS;
393     }
394     EC_GROUP *ecGroup = NULL;
395     EC_POINT *ecPoint = NULL;
396     BIGNUM *x = NULL;
397     BIGNUM *y = NULL;
398     HcfBigInteger tmpBigIntX = { .data = NULL, .len = 0 };
399     HcfBigInteger tmpBigIntY = { .data = NULL, .len = 0 };
400     HcfResult ret = HCF_SUCCESS;
401     do {
402         ret = InitEccPoint(curveNameValue, &ecGroup, &ecPoint, &x, &y);
403         if (ret != HCF_SUCCESS) {
404             LOGE("Failed to get EccPoint.");
405             break;
406         }
407         if (!OpensslEcOct2Point(ecGroup, ecPoint, pointBlob->data, pointBlob->len, NULL)) {
408             LOGE("Failed to convert pointBlob data to EC_POINT.");
409             HcfPrintOpensslError();
410             ret = HCF_ERR_CRYPTO_OPERATION;
411             break;
412         }
413         if (!OpensslEcPointGetAffineCoordinates(ecGroup, ecPoint, x, y, NULL)) {
414             LOGE("Failed to get affine coordinates from EC_POINT.");
415             ret = HCF_ERR_CRYPTO_OPERATION;
416             break;
417         }
418         ret = ConvertBigNumToEccPoint(x, y, &tmpBigIntX, &tmpBigIntY);
419         if (ret != HCF_SUCCESS) {
420             LOGE("Failed to convert BIGNUMs to HcfBigIntegers.");
421             break;
422         }
423         returnPoint->x = tmpBigIntX;
424         returnPoint->y = tmpBigIntY;
425     } while (0);
426     OpensslEcGroupFree(ecGroup);
427     OpensslEcPointFree(ecPoint);
428     OpensslBnFree(x);
429     OpensslBnFree(y);
430     return ret;
431 }
432 
HcfEngineGetEncodedPoint(const int32_t curveNameValue,HcfPoint * point,const int32_t formatValue,HcfBlob * returnBlob)433 HcfResult HcfEngineGetEncodedPoint(const int32_t curveNameValue, HcfPoint *point,
434                                    const int32_t formatValue, HcfBlob *returnBlob)
435 {
436     if ((curveNameValue == 0) || (point == NULL) || (formatValue == 0) || (returnBlob == NULL)) {
437         LOGE("Invalid input parameter.");
438         return HCF_INVALID_PARAMS;
439     }
440     EC_GROUP *ecGroup = NULL;
441     EC_POINT *ecPoint = NULL;
442     BIGNUM *bnX = NULL;
443     BIGNUM *bnY = NULL;
444     HcfResult ret = HCF_SUCCESS;
445     do {
446         ret = InitEccPoint(curveNameValue, &ecGroup, &ecPoint, NULL, NULL);
447         if (ret != HCF_SUCCESS) {
448             LOGE("Failed to get EccPoint.");
449             break;
450         }
451         ret = BigIntegerToBigNum(&(point->x), &bnX);
452         if (ret != HCF_SUCCESS) {
453             LOGE("Failed to convert HcfBigInteger to XBIGNUMs.");
454             break;
455         }
456         ret = BigIntegerToBigNum(&(point->y), &bnY);
457         if (ret != HCF_SUCCESS) {
458             LOGE("Failed to convert HcfBigInteger to YBIGNUMs.");
459             break;
460         }
461         if (OpensslEcPointSetAffineCoordinates(ecGroup, ecPoint, bnX, bnY, NULL) != HCF_OPENSSL_SUCCESS) {
462             LOGE("Failed to set point coordinates.");
463             HcfPrintOpensslError();
464             ret = HCF_ERR_CRYPTO_OPERATION;
465             break;
466         }
467         ret = GetECCPointEncoded(formatValue, ecGroup, ecPoint, returnBlob);
468         if (ret != HCF_SUCCESS) {
469             LOGE("Failed to get EccPointEncoded.");
470             break;
471         }
472     } while (0);
473     OpensslEcGroupFree(ecGroup);
474     OpensslEcPointFree(ecPoint);
475     OpensslBnFree(bnX);
476     OpensslBnFree(bnY);
477     return ret;
478 }
479