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.h"
17 #include "securec.h"
18 #include "asy_key_generator.h"
19 #include "ecc_key_util.h"
20 #include "memory.h"
21 #include "memory_mock.h"
22 
23 static char *g_brainpool160r1AlgName = "ECC_BrainPoolP160r1";
24 HcfEccCommParamsSpec *g_eccCommSpec = NULL;
25 
ConstructEccKeyPairCommParamsSpec(const char * algoName,HcfEccCommParamsSpec ** spec)26 HcfResult ConstructEccKeyPairCommParamsSpec(const char *algoName, HcfEccCommParamsSpec **spec)
27 {
28     HcfEccCommParamsSpec *eccCommSpec = NULL;
29     HcfEccKeyUtilCreate(algoName, &eccCommSpec);
30     if (eccCommSpec == NULL) {
31         return HCF_INVALID_PARAMS;
32     }
33     *spec = eccCommSpec;
34     return HCF_SUCCESS;
35 }
36 
ConstructEccKeyPairBigInt(HcfKeyPair * keyPair,HcfEccKeyPairParamsSpec * eccKeyPairSpec)37 static HcfResult ConstructEccKeyPairBigInt(HcfKeyPair *keyPair, HcfEccKeyPairParamsSpec *eccKeyPairSpec)
38 {
39     HcfBigInteger retBigInt = { .data = NULL, .len = 0 };
40     HcfResult res = keyPair->pubKey->getAsyKeySpecBigInteger(keyPair->pubKey, ECC_PK_X_BN, &retBigInt);
41     if (res != HCF_SUCCESS) {
42         return res;
43     }
44     eccKeyPairSpec->pk.x.data = retBigInt.data;
45     eccKeyPairSpec->pk.x.len = retBigInt.len;
46 
47     res = keyPair->pubKey->getAsyKeySpecBigInteger(keyPair->pubKey, ECC_PK_Y_BN, &retBigInt);
48     if (res != HCF_SUCCESS) {
49         HcfFree(eccKeyPairSpec->pk.x.data);
50         eccKeyPairSpec->pk.x.data = NULL;
51         eccKeyPairSpec->pk.x.len = 0;
52         return res;
53     }
54     eccKeyPairSpec->pk.y.data = retBigInt.data;
55     eccKeyPairSpec->pk.y.len = retBigInt.len;
56 
57     res = keyPair->priKey->getAsyKeySpecBigInteger(keyPair->priKey, ECC_SK_BN, &retBigInt);
58     if (res != HCF_SUCCESS) {
59         HcfFree(eccKeyPairSpec->pk.x.data);
60         eccKeyPairSpec->pk.x.data = NULL;
61         eccKeyPairSpec->pk.x.len = 0;
62         HcfFree(eccKeyPairSpec->pk.y.data);
63         eccKeyPairSpec->pk.y.data = NULL;
64         eccKeyPairSpec->pk.y.len = 0;
65         return res;
66     }
67     eccKeyPairSpec->sk.data = retBigInt.data;
68     eccKeyPairSpec->sk.len = retBigInt.len;
69     return HCF_SUCCESS;
70 }
71 
ConstructEccKeyPairParamsSpec(const char * algoName,HcfEccCommParamsSpec * eccCommSpec,HcfAsyKeyParamsSpec ** spec)72 HcfResult ConstructEccKeyPairParamsSpec(const char *algoName, HcfEccCommParamsSpec *eccCommSpec,
73     HcfAsyKeyParamsSpec **spec)
74 {
75     if (eccCommSpec == NULL) {
76         return HCF_INVALID_PARAMS;
77     }
78     HcfAsyKeyGenerator *generator = NULL;
79     HcfResult res = HCF_ERR_CRYPTO_OPERATION;
80     if (HcfAsyKeyGeneratorCreate(algoName, &generator) != HCF_SUCCESS) {
81         return res;
82     }
83     HcfKeyPair *keyPair = NULL;
84     if (generator->generateKeyPair(generator, NULL, &keyPair) != HCF_SUCCESS) {
85         HcfObjDestroy(generator);
86         return res;
87     }
88 
89     HcfEccKeyPairParamsSpec *eccKeyPairSpec = (HcfEccKeyPairParamsSpec*)HcfMalloc(sizeof(HcfEccKeyPairParamsSpec), 0);
90     if (eccKeyPairSpec != NULL) {
91         eccKeyPairSpec->base.base.algName = eccCommSpec->base.algName;
92         eccKeyPairSpec->base.base.specType = HCF_KEY_PAIR_SPEC;
93         eccKeyPairSpec->base.field = eccCommSpec->field;
94         eccKeyPairSpec->base.field->fieldType = eccCommSpec->field->fieldType;
95         ((HcfECFieldFp *)(eccKeyPairSpec->base.field))->p.data = ((HcfECFieldFp *)(eccCommSpec->field))->p.data;
96         ((HcfECFieldFp *)(eccKeyPairSpec->base.field))->p.len = ((HcfECFieldFp *)(eccCommSpec->field))->p.len;
97         eccKeyPairSpec->base.a.data = eccCommSpec->a.data;
98         eccKeyPairSpec->base.a.len = eccCommSpec->a.len;
99         eccKeyPairSpec->base.b.data = eccCommSpec->b.data;
100         eccKeyPairSpec->base.b.len = eccCommSpec->b.len;
101         eccKeyPairSpec->base.g.x.data = eccCommSpec->g.x.data;
102         eccKeyPairSpec->base.g.x.len = eccCommSpec->g.x.len;
103         eccKeyPairSpec->base.g.y.data = eccCommSpec->g.y.data;
104         eccKeyPairSpec->base.g.y.len = eccCommSpec->g.y.len;
105         eccKeyPairSpec->base.n.data = eccCommSpec->n.data;
106         eccKeyPairSpec->base.n.len = eccCommSpec->n.len;
107         eccKeyPairSpec->base.h = eccCommSpec->h;
108         if (ConstructEccKeyPairBigInt(keyPair, eccKeyPairSpec) != HCF_SUCCESS) {
109             HcfFree(eccKeyPairSpec);
110         } else {
111             *spec = (HcfAsyKeyParamsSpec *)eccKeyPairSpec;
112             res = HCF_SUCCESS;
113         }
114     }
115     HcfObjDestroy(generator);
116     HcfObjDestroy(keyPair);
117     return res;
118 }
119 
ConstructEccPubKeyBigInt(HcfKeyPair * keyPair,HcfEccPubKeyParamsSpec * eccPubKeySpec)120 static HcfResult ConstructEccPubKeyBigInt(HcfKeyPair *keyPair, HcfEccPubKeyParamsSpec *eccPubKeySpec)
121 {
122     HcfBigInteger retBigInt = { .data = NULL, .len = 0 };
123     HcfResult res = keyPair->pubKey->getAsyKeySpecBigInteger(keyPair->pubKey, ECC_PK_X_BN, &retBigInt);
124     if (res != HCF_SUCCESS) {
125         return res;
126     }
127     eccPubKeySpec->pk.x.data = retBigInt.data;
128     eccPubKeySpec->pk.x.len = retBigInt.len;
129 
130     res = keyPair->pubKey->getAsyKeySpecBigInteger(keyPair->pubKey, ECC_PK_Y_BN, &retBigInt);
131     if (res != HCF_SUCCESS) {
132         HcfFree(eccPubKeySpec->pk.x.data);
133         eccPubKeySpec->pk.x.data = NULL;
134         eccPubKeySpec->pk.x.len = 0;
135         return res;
136     }
137     eccPubKeySpec->pk.y.data = retBigInt.data;
138     eccPubKeySpec->pk.y.len = retBigInt.len;
139     return HCF_SUCCESS;
140 }
141 
ConstructEccPubKeyParamsSpec(const char * algoName,HcfEccCommParamsSpec * eccCommSpec,HcfAsyKeyParamsSpec ** spec)142 HcfResult ConstructEccPubKeyParamsSpec(const char *algoName, HcfEccCommParamsSpec *eccCommSpec,
143     HcfAsyKeyParamsSpec **spec)
144 {
145     if (eccCommSpec == NULL) {
146         return HCF_INVALID_PARAMS;
147     }
148 
149     HcfResult res = HCF_ERR_CRYPTO_OPERATION;
150     HcfAsyKeyGenerator *generator = NULL;
151     if (HcfAsyKeyGeneratorCreate(algoName, &generator) != HCF_SUCCESS) {
152         return res;
153     }
154 
155     HcfKeyPair *keyPair = NULL;
156     if (generator->generateKeyPair(generator, NULL, &keyPair) != HCF_SUCCESS) {
157         HcfObjDestroy(generator);
158         return res;
159     }
160 
161     HcfEccPubKeyParamsSpec *eccPubKeySpec = (HcfEccPubKeyParamsSpec*)HcfMalloc(sizeof(HcfEccPubKeyParamsSpec), 0);
162     if (eccPubKeySpec != NULL) {
163         eccPubKeySpec->base.base.algName = eccCommSpec->base.algName;
164         eccPubKeySpec->base.base.specType = HCF_PUBLIC_KEY_SPEC;
165         eccPubKeySpec->base.field = eccCommSpec->field;
166         eccPubKeySpec->base.field->fieldType = eccCommSpec->field->fieldType;
167         ((HcfECFieldFp *)(eccPubKeySpec->base.field))->p.data = ((HcfECFieldFp *)(eccCommSpec->field))->p.data;
168         ((HcfECFieldFp *)(eccPubKeySpec->base.field))->p.len = ((HcfECFieldFp *)(eccCommSpec->field))->p.len;
169         eccPubKeySpec->base.a.data = eccCommSpec->a.data;
170         eccPubKeySpec->base.a.len = eccCommSpec->a.len;
171         eccPubKeySpec->base.b.data = eccCommSpec->b.data;
172         eccPubKeySpec->base.b.len = eccCommSpec->b.len;
173         eccPubKeySpec->base.g.x.data = eccCommSpec->g.x.data;
174         eccPubKeySpec->base.g.x.len = eccCommSpec->g.x.len;
175         eccPubKeySpec->base.g.y.data = eccCommSpec->g.y.data;
176         eccPubKeySpec->base.g.y.len = eccCommSpec->g.y.len;
177         eccPubKeySpec->base.n.data = eccCommSpec->n.data;
178         eccPubKeySpec->base.n.len = eccCommSpec->n.len;
179         eccPubKeySpec->base.h = eccCommSpec->h;
180         if (ConstructEccPubKeyBigInt(keyPair, eccPubKeySpec) != HCF_SUCCESS) {
181             HcfFree(eccPubKeySpec);
182         } else {
183             *spec = (HcfAsyKeyParamsSpec *)eccPubKeySpec;
184             res = HCF_SUCCESS;
185         }
186     }
187 
188     HcfObjDestroy(generator);
189     HcfObjDestroy(keyPair);
190     return res;
191 }
192 
ConstructEccPriKeyParamsSpec(const char * algoName,HcfEccCommParamsSpec * eccCommSpec,HcfAsyKeyParamsSpec ** spec)193 HcfResult ConstructEccPriKeyParamsSpec(const char *algoName, HcfEccCommParamsSpec *eccCommSpec,
194     HcfAsyKeyParamsSpec **spec)
195 {
196     if (eccCommSpec == NULL) {
197         return HCF_INVALID_PARAMS;
198     }
199 
200     HcfResult res = HCF_ERR_CRYPTO_OPERATION;
201     HcfAsyKeyGenerator *generator = NULL;
202     if (HcfAsyKeyGeneratorCreate(algoName, &generator) != HCF_SUCCESS) {
203         return res;
204     }
205 
206     HcfKeyPair *keyPair = NULL;
207     if (generator->generateKeyPair(generator, NULL, &keyPair) != HCF_SUCCESS) {
208         HcfObjDestroy(generator);
209         return res;
210     }
211 
212     HcfEccPriKeyParamsSpec *eccPriKeySpec = (HcfEccPriKeyParamsSpec*)HcfMalloc(sizeof(HcfEccPriKeyParamsSpec), 0);
213     if (eccPriKeySpec != NULL) {
214         eccPriKeySpec->base.base.algName = eccCommSpec->base.algName;
215         eccPriKeySpec->base.base.specType = HCF_PRIVATE_KEY_SPEC;
216         eccPriKeySpec->base.field = eccCommSpec->field;
217         eccPriKeySpec->base.field->fieldType = eccCommSpec->field->fieldType;
218         ((HcfECFieldFp *)(eccPriKeySpec->base.field))->p.data = ((HcfECFieldFp *)(eccCommSpec->field))->p.data;
219         ((HcfECFieldFp *)(eccPriKeySpec->base.field))->p.len = ((HcfECFieldFp *)(eccCommSpec->field))->p.len;
220         eccPriKeySpec->base.a.data = eccCommSpec->a.data;
221         eccPriKeySpec->base.a.len = eccCommSpec->a.len;
222         eccPriKeySpec->base.b.data = eccCommSpec->b.data;
223         eccPriKeySpec->base.b.len = eccCommSpec->b.len;
224         eccPriKeySpec->base.g.x.data = eccCommSpec->g.x.data;
225         eccPriKeySpec->base.g.x.len = eccCommSpec->g.x.len;
226         eccPriKeySpec->base.g.y.data = eccCommSpec->g.y.data;
227         eccPriKeySpec->base.g.y.len = eccCommSpec->g.y.len;
228         eccPriKeySpec->base.n.data = eccCommSpec->n.data;
229         eccPriKeySpec->base.n.len = eccCommSpec->n.len;
230         eccPriKeySpec->base.h = eccCommSpec->h;
231         HcfBigInteger retBigInt = { .data = NULL, .len = 0 };
232         if (keyPair->priKey->getAsyKeySpecBigInteger(keyPair->priKey, ECC_SK_BN, &retBigInt) != HCF_SUCCESS) {
233             HcfFree(eccPriKeySpec);
234         } else {
235             eccPriKeySpec->sk.data = retBigInt.data;
236             eccPriKeySpec->sk.len = retBigInt.len;
237             *spec = (HcfAsyKeyParamsSpec *)eccPriKeySpec;
238             res = HCF_SUCCESS;
239         }
240     }
241     HcfObjDestroy(generator);
242     HcfObjDestroy(keyPair);
243     return res;
244 }
245 
GenerateBrainpoolP160r1KeyPair(HcfKeyPair ** keyPair)246 HcfResult GenerateBrainpoolP160r1KeyPair(HcfKeyPair **keyPair)
247 {
248     HcfResult res = ConstructEccKeyPairCommParamsSpec("NID_brainpoolP160r1", &g_eccCommSpec);
249     if (res != HCF_SUCCESS) {
250         return res;
251     }
252     HcfAsyKeyParamsSpec *paramSpec = NULL;
253     res = ConstructEccKeyPairParamsSpec(g_brainpool160r1AlgName, g_eccCommSpec, &paramSpec);
254     if (res != HCF_SUCCESS) {
255         return res;
256     }
257     HcfAsyKeyGeneratorBySpec *generator = NULL;
258     res = HcfAsyKeyGeneratorBySpecCreate(paramSpec, &generator);
259     if (res != HCF_SUCCESS) {
260         return res;
261     }
262     res = generator->generateKeyPair(generator, keyPair);
263     if (res != HCF_SUCCESS) {
264         HcfObjDestroy(generator);
265         return res;
266     }
267     HcfObjDestroy(generator);
268     DestroyEccKeyPairSpec((HcfEccKeyPairParamsSpec *)paramSpec);
269     return HCF_SUCCESS;
270 }
271