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