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