• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 = Openssl_EC_POINT_new(ecGroup);
31     if (point == NULL) {
32         LOGE("new ec point failed.");
33         return NULL;
34     }
35     const EC_POINT *tmpPoint = Openssl_EC_GROUP_get0_generator(ecGroup);
36     if (tmpPoint == NULL) {
37         LOGE("Get ec generator failed.");
38         Openssl_EC_POINT_free(point);
39         return NULL;
40     }
41     if (!Openssl_EC_POINT_copy(point, tmpPoint)) {
42         LOGE("Ec point copy failed.");
43         Openssl_EC_POINT_free(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 = Openssl_BN_new();
59     if (x == NULL) {
60         LOGE("New x failed.");
61         Openssl_EC_POINT_free(point);
62         return HCF_ERR_MALLOC;
63     }
64     BIGNUM *y = Openssl_BN_new();
65     if (y == NULL) {
66         LOGE("New y failed.");
67         Openssl_BN_free(x);
68         Openssl_EC_POINT_free(point);
69         return HCF_ERR_MALLOC;
70     }
71     HcfResult ret = HCF_SUCCESS;
72     do {
73         if (!Openssl_EC_POINT_get_affine_coordinates_GFp(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     Openssl_BN_free(x);
90     Openssl_BN_free(y);
91     Openssl_EC_POINT_free(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 = Openssl_BN_new();
98     if (p == NULL) {
99         LOGE("New p failed.");
100         return HCF_ERR_MALLOC;
101     }
102     BIGNUM *a = Openssl_BN_new();
103     if (a == NULL) {
104         LOGE("New a failed.");
105         Openssl_BN_free(p);
106         return HCF_ERR_MALLOC;
107     }
108     BIGNUM *b = Openssl_BN_new();
109     if (b == NULL) {
110         LOGE("New b failed.");
111         Openssl_BN_free(p);
112         Openssl_BN_free(a);
113         return HCF_ERR_MALLOC;
114     }
115     if (!Openssl_EC_GROUP_get_curve_GFp(ecGroup, p, a, b, NULL)) {
116         LOGE("EC_GROUP_get_curve_GFp failed.");
117         Openssl_BN_free(p);
118         Openssl_BN_free(a);
119         Openssl_BN_free(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     Openssl_BN_free(p);
144     Openssl_BN_free(a);
145     Openssl_BN_free(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         HcfFree(spec->paramsSpec.field->fieldType);
220         spec->paramsSpec.field->fieldType = NULL;
221         HcfFree(spec->paramsSpec.field);
222         spec->paramsSpec.field = NULL;
223     }
224     HcfFree(spec->paramsSpec.a.data);
225     spec->paramsSpec.a.data = NULL;
226     HcfFree(spec->paramsSpec.b.data);
227     spec->paramsSpec.b.data = NULL;
228     HcfFree(spec->paramsSpec.n.data);
229     spec->paramsSpec.n.data = NULL;
230     HcfFree(spec->paramsSpec.g.x.data);
231     spec->paramsSpec.g.x.data = NULL;
232     HcfFree(spec->paramsSpec.g.y.data);
233     spec->paramsSpec.g.y.data = NULL;
234     HcfFree(spec);
235 }
236 
HcfECCCommonParamSpecCreate(HcfAsyKeyGenParams * params,HcfEccCommParamsSpecSpi ** returnCommonParamSpec)237 HcfResult HcfECCCommonParamSpecCreate(HcfAsyKeyGenParams *params, HcfEccCommParamsSpecSpi **returnCommonParamSpec)
238 {
239     if ((params == NULL) || (returnCommonParamSpec == NULL)) {
240         LOGE("Invalid input parameter.");
241         return HCF_INVALID_PARAMS;
242     }
243     int32_t curveId = 0;
244     if (params->bits != 0) {
245         if (GetOpensslCurveId(params->bits, &curveId) != HCF_SUCCESS) {
246             LOGE("Get curveId parameter failed.");
247             return HCF_INVALID_PARAMS;
248         }
249     }
250     EC_GROUP *ecGroup = Openssl_EC_GROUP_new_by_curve_name(curveId);
251     if (ecGroup == NULL) {
252         LOGE("Create ecGroup failed.");
253         return HCF_ERR_CRYPTO_OPERATION;
254     }
255     HcfEccCommParamsSpecSpi *object = BuildEccCommonParamObject();
256     if (object == NULL) {
257         LOGE("Build ecc common params object failed.");
258         Openssl_EC_GROUP_free(ecGroup);
259         return HCF_ERR_MALLOC;
260     }
261     object->paramsSpec.base.specType = HCF_COMMON_PARAMS_SPEC;
262     if (GetAlgNameByBits(params->bits, &(object->paramsSpec.base.algName)) != HCF_SUCCESS) {
263         LOGE("Get algName parameter by bits failed.");
264         FreeEccCommParamObject(object);
265         object = NULL;
266         Openssl_EC_GROUP_free(ecGroup);
267         return HCF_INVALID_PARAMS;
268     }
269     if (BuildCommonParam(ecGroup, object)!= HCF_SUCCESS) {
270         LOGE("Get common params failed.");
271         FreeEccCommParamObject(object);
272         object = NULL;
273         Openssl_EC_GROUP_free(ecGroup);
274         return HCF_ERR_CRYPTO_OPERATION;
275     }
276     *returnCommonParamSpec = object;
277     Openssl_EC_GROUP_free(ecGroup);
278     return HCF_SUCCESS;
279 }
280