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 "asy_key_params.h"
17
18#include <stdio.h>
19#include <string.h>
20#include <securec.h>
21#include "params_parser.h"
22#include "big_integer.h"
23#include "detailed_dsa_key_params.h"
24#include "detailed_dh_key_params.h"
25#include "detailed_ecc_key_params.h"
26#include "detailed_rsa_key_params.h"
27#include "detailed_alg_25519_key_params.h"
28#include "sm2_crypto_params.h"
29#include "memory.h"
30#include "log.h"
31
32#define ALG_NAME_DSA "DSA"
33#define ALG_NAME_ECC "ECC"
34#define ALG_NAME_SM2 "SM2"
35#define ALG_NAME_RSA "RSA"
36#define ALG_NAME_DH "DH"
37#define ALG_NAME_ED25519 "Ed25519"
38#define ALG_NAME_X25519 "X25519"
39
40typedef void (*HcfFreeParamsAsyKeySpec)(HcfAsyKeyParamsSpec *);
41
42typedef struct {
43    char *algo;
44
45    HcfFreeParamsAsyKeySpec createFreeFunc;
46} HcfFreeAsyKeySpec;
47
48void FreeDsaCommParamsSpec(HcfDsaCommParamsSpec *spec)
49{
50    if (spec == NULL) {
51        return;
52    }
53    HcfFree(spec->base.algName);
54    spec->base.algName = NULL;
55    HcfFree(spec->p.data);
56    spec->p.data = NULL;
57    HcfFree(spec->q.data);
58    spec->q.data = NULL;
59    HcfFree(spec->g.data);
60    spec->g.data = NULL;
61}
62
63void FreeDhCommParamsSpec(HcfDhCommParamsSpec *spec)
64{
65    if (spec == NULL) {
66        return;
67    }
68    HcfFree(spec->base.algName);
69    spec->base.algName = NULL;
70    HcfFree(spec->p.data);
71    spec->p.data = NULL;
72    HcfFree(spec->g.data);
73    spec->g.data = NULL;
74}
75
76static void DestroyDsaCommParamsSpec(HcfDsaCommParamsSpec *spec)
77{
78    FreeDsaCommParamsSpec(spec);
79    HcfFree(spec);
80}
81
82void DestroyDsaPubKeySpec(HcfDsaPubKeyParamsSpec *spec)
83{
84    if (spec == NULL) {
85        return;
86    }
87    FreeDsaCommParamsSpec(&(spec->base));
88    HcfFree(spec->pk.data);
89    spec->pk.data = NULL;
90    HcfFree(spec);
91}
92
93void DestroyDsaKeyPairSpec(HcfDsaKeyPairParamsSpec *spec)
94{
95    if (spec == NULL) {
96        return;
97    }
98    FreeDsaCommParamsSpec(&(spec->base));
99    HcfFree(spec->pk.data);
100    spec->pk.data = NULL;
101    if (spec->sk.data != NULL) {
102        (void)memset_s(spec->sk.data, spec->sk.len, 0, spec->sk.len);
103        HcfFree(spec->sk.data);
104        spec->sk.data = NULL;
105    }
106    HcfFree(spec);
107}
108
109static void DestroyDhCommParamsSpec(HcfDhCommParamsSpec *spec)
110{
111    FreeDhCommParamsSpec(spec);
112    HcfFree(spec);
113}
114
115void DestroyDhPubKeySpec(HcfDhPubKeyParamsSpec *spec)
116{
117    if (spec == NULL) {
118        return;
119    }
120    FreeDhCommParamsSpec(&(spec->base));
121    HcfFree(spec->pk.data);
122    spec->pk.data = NULL;
123    HcfFree(spec);
124}
125
126void DestroyDhPriKeySpec(HcfDhPriKeyParamsSpec *spec)
127{
128    if (spec == NULL) {
129        return;
130    }
131    FreeDhCommParamsSpec(&(spec->base));
132    if (spec->sk.data != NULL) {
133        (void)memset_s(spec->sk.data, spec->sk.len, 0, spec->sk.len);
134        HcfFree(spec->sk.data);
135        spec->sk.data = NULL;
136    }
137    HcfFree(spec);
138}
139
140void DestroyDhKeyPairSpec(HcfDhKeyPairParamsSpec *spec)
141{
142    if (spec == NULL) {
143        return;
144    }
145    FreeDhCommParamsSpec(&(spec->base));
146    HcfFree(spec->pk.data);
147    spec->pk.data = NULL;
148    if (spec->sk.data != NULL) {
149        (void)memset_s(spec->sk.data, spec->sk.len, 0, spec->sk.len);
150        HcfFree(spec->sk.data);
151        spec->sk.data = NULL;
152    }
153    HcfFree(spec);
154}
155
156static void FreeEcFieldMem(HcfECField **field)
157{
158    HcfFree((*field)->fieldType);
159    (*field)->fieldType = NULL;
160    HcfFree(((HcfECFieldFp *)(*field))->p.data);
161    ((HcfECFieldFp *)(*field))->p.data = NULL;
162    HcfFree(*field);
163    *field = NULL;
164}
165
166void FreeEcPointMem(HcfPoint *point)
167{
168    if (point == NULL) {
169        return;
170    }
171    HcfFree(point->x.data);
172    point->x.data = NULL;
173    HcfFree(point->y.data);
174    point->y.data = NULL;
175}
176
177void FreeEccCommParamsSpec(HcfEccCommParamsSpec *spec)
178{
179    if (spec == NULL) {
180        return;
181    }
182    HcfFree(spec->base.algName);
183    spec->base.algName = NULL;
184    HcfFree(spec->a.data);
185    spec->a.data = NULL;
186    HcfFree(spec->b.data);
187    spec->b.data = NULL;
188    HcfFree(spec->n.data);
189    spec->n.data = NULL;
190    FreeEcFieldMem(&(spec->field));
191    spec->field = NULL;
192    FreeEcPointMem(&(spec->g));
193}
194
195static void DestroyEccCommParamsSpec(HcfEccCommParamsSpec *spec)
196{
197    FreeEccCommParamsSpec(spec);
198    HcfFree(spec);
199}
200
201void DestroyEccPubKeySpec(HcfEccPubKeyParamsSpec *spec)
202{
203    if (spec == NULL) {
204        return;
205    }
206    FreeEccCommParamsSpec(&(spec->base));
207    FreeEcPointMem(&(spec->pk));
208    HcfFree(spec);
209}
210
211void DestroyEccPriKeySpec(HcfEccPriKeyParamsSpec *spec)
212{
213    if (spec == NULL) {
214        return;
215    }
216    FreeEccCommParamsSpec(&(spec->base));
217    if (spec->sk.data != NULL) {
218        (void)memset_s(spec->sk.data, spec->sk.len, 0, spec->sk.len);
219        HcfFree(spec->sk.data);
220        spec->sk.data = NULL;
221    }
222    HcfFree(spec);
223}
224
225void DestroyEccKeyPairSpec(HcfEccKeyPairParamsSpec *spec)
226{
227    if (spec == NULL) {
228        return;
229    }
230    FreeEccCommParamsSpec(&(spec->base));
231    FreeEcPointMem(&(spec->pk));
232    if (spec->sk.data != NULL) {
233        (void)memset_s(spec->sk.data, spec->sk.len, 0, spec->sk.len);
234        HcfFree(spec->sk.data);
235        spec->sk.data = NULL;
236    }
237    HcfFree(spec);
238}
239
240void FreeRsaCommParamsSpec(HcfRsaCommParamsSpec *spec)
241{
242    if (spec == NULL) {
243        return;
244    }
245    HcfFree(spec->base.algName);
246    spec->base.algName = NULL;
247    HcfFree(spec->n.data);
248    spec->n.data = NULL;
249}
250
251static void DestroyRsaCommParamsSpec(HcfRsaCommParamsSpec *spec)
252{
253    FreeRsaCommParamsSpec(spec);
254    HcfFree(spec);
255}
256
257void DestroyRsaPubKeySpec(HcfRsaPubKeyParamsSpec *spec)
258{
259    if (spec == NULL) {
260        return;
261    }
262    FreeRsaCommParamsSpec(&(spec->base));
263    HcfFree(spec->pk.data);
264    spec->pk.data = NULL;
265    HcfFree(spec);
266}
267
268void DestroyRsaKeyPairSpec(HcfRsaKeyPairParamsSpec *spec)
269{
270    if (spec == NULL) {
271        return;
272    }
273    FreeRsaCommParamsSpec(&(spec->base));
274    HcfFree(spec->pk.data);
275    spec->pk.data = NULL;
276    if (spec->sk.data != NULL) {
277        (void)memset_s(spec->sk.data, spec->sk.len, 0, spec->sk.len);
278        HcfFree(spec->sk.data);
279        spec->sk.data = NULL;
280    }
281    HcfFree(spec);
282}
283
284static void DestroyDsaParamsSpec(HcfAsyKeyParamsSpec *spec)
285{
286    switch (spec->specType) {
287        case HCF_COMMON_PARAMS_SPEC:
288            DestroyDsaCommParamsSpec((HcfDsaCommParamsSpec *)spec);
289            break;
290        case HCF_PUBLIC_KEY_SPEC:
291            DestroyDsaPubKeySpec((HcfDsaPubKeyParamsSpec *)spec);
292            break;
293        case HCF_KEY_PAIR_SPEC:
294            DestroyDsaKeyPairSpec((HcfDsaKeyPairParamsSpec *)spec);
295            break;
296        default:
297            LOGE("No matching DSA key params spec type.");
298            break;
299    }
300}
301
302static void DestroyDhParamsSpec(HcfAsyKeyParamsSpec *spec)
303{
304    switch (spec->specType) {
305        case HCF_COMMON_PARAMS_SPEC:
306            DestroyDhCommParamsSpec((HcfDhCommParamsSpec *)spec);
307            break;
308        case HCF_PUBLIC_KEY_SPEC:
309            DestroyDhPubKeySpec((HcfDhPubKeyParamsSpec *)spec);
310            break;
311        case HCF_PRIVATE_KEY_SPEC:
312            DestroyDhPriKeySpec((HcfDhPriKeyParamsSpec *)spec);
313            break;
314        case HCF_KEY_PAIR_SPEC:
315            DestroyDhKeyPairSpec((HcfDhKeyPairParamsSpec *)spec);
316            break;
317        default:
318            LOGE("No matching DH key params spec type.");
319            break;
320    }
321}
322
323static void DestroyEccParamsSpec(HcfAsyKeyParamsSpec *spec)
324{
325    switch (spec->specType) {
326        case HCF_COMMON_PARAMS_SPEC:
327            DestroyEccCommParamsSpec((HcfEccCommParamsSpec *)spec);
328            break;
329        case HCF_PRIVATE_KEY_SPEC:
330            DestroyEccPriKeySpec((HcfEccPriKeyParamsSpec *)spec);
331            break;
332        case HCF_PUBLIC_KEY_SPEC:
333            DestroyEccPubKeySpec((HcfEccPubKeyParamsSpec *)spec);
334            break;
335        case HCF_KEY_PAIR_SPEC:
336            DestroyEccKeyPairSpec((HcfEccKeyPairParamsSpec *)spec);
337            break;
338        default:
339            LOGE("No matching ECC key params spec type.");
340            break;
341    }
342}
343
344static void DestroyRsaParamsSpec(HcfAsyKeyParamsSpec *spec)
345{
346    switch (spec->specType) {
347        case HCF_COMMON_PARAMS_SPEC:
348            DestroyRsaCommParamsSpec((HcfRsaCommParamsSpec *)spec);
349            break;
350        case HCF_PUBLIC_KEY_SPEC:
351            DestroyRsaPubKeySpec((HcfRsaPubKeyParamsSpec *)spec);
352            break;
353        case HCF_KEY_PAIR_SPEC:
354            DestroyRsaKeyPairSpec((HcfRsaKeyPairParamsSpec *)spec);
355            break;
356        default:
357            LOGE("No matching RSA key params spec type.");
358            break;
359    }
360}
361
362void DestroyAlg25519PubKeySpec(HcfAlg25519PubKeyParamsSpec *spec)
363{
364    if (spec == NULL) {
365        return;
366    }
367    if (spec->pk.data != NULL) {
368        (void)memset_s(spec->pk.data, spec->pk.len, 0, spec->pk.len);
369        HcfFree(spec->pk.data);
370        spec->pk.data = NULL;
371    }
372    if (spec->base.algName != NULL) {
373        HcfFree(spec->base.algName);
374        spec->base.algName = NULL;
375    }
376    HcfFree(spec);
377}
378
379void DestroyAlg25519PriKeySpec(HcfAlg25519PriKeyParamsSpec *spec)
380{
381    if (spec == NULL) {
382        return;
383    }
384    if (spec->sk.data != NULL) {
385        (void)memset_s(spec->sk.data, spec->sk.len, 0, spec->sk.len);
386        HcfFree(spec->sk.data);
387        spec->sk.data = NULL;
388    }
389    if (spec->base.algName != NULL) {
390        HcfFree(spec->base.algName);
391        spec->base.algName = NULL;
392    }
393    HcfFree(spec);
394}
395
396void DestroyAlg25519KeyPairSpec(HcfAlg25519KeyPairParamsSpec *spec)
397{
398    if (spec == NULL) {
399        return;
400    }
401    if (spec->pk.data != NULL) {
402        (void)memset_s(spec->pk.data, spec->pk.len, 0, spec->pk.len);
403        HcfFree(spec->pk.data);
404        spec->pk.data = NULL;
405    }
406    if (spec->sk.data != NULL) {
407        (void)memset_s(spec->sk.data, spec->sk.len, 0, spec->sk.len);
408        HcfFree(spec->sk.data);
409        spec->sk.data = NULL;
410    }
411    if (spec->base.algName != NULL) {
412        HcfFree(spec->base.algName);
413        spec->base.algName = NULL;
414    }
415    HcfFree(spec);
416}
417
418static void DestroyAlg25519ParamsSpec(HcfAsyKeyParamsSpec *spec)
419{
420    switch (spec->specType) {
421        case HCF_PUBLIC_KEY_SPEC:
422            DestroyAlg25519PubKeySpec((HcfAlg25519PubKeyParamsSpec *)spec);
423            break;
424        case HCF_PRIVATE_KEY_SPEC:
425            DestroyAlg25519PriKeySpec((HcfAlg25519PriKeyParamsSpec *)spec);
426            break;
427        case HCF_KEY_PAIR_SPEC:
428            DestroyAlg25519KeyPairSpec((HcfAlg25519KeyPairParamsSpec *)spec);
429            break;
430        default:
431            LOGE("No matching alg25519 key params spec type.");
432            break;
433    }
434}
435
436static HcfFreeAsyKeySpec g_asyKeyFreeAbility[] = {
437    { ALG_NAME_DSA, DestroyDsaParamsSpec },
438    { ALG_NAME_ECC, DestroyEccParamsSpec },
439    { ALG_NAME_SM2, DestroyEccParamsSpec },
440    { ALG_NAME_RSA, DestroyRsaParamsSpec },
441    { ALG_NAME_X25519, DestroyAlg25519ParamsSpec },
442    { ALG_NAME_ED25519, DestroyAlg25519ParamsSpec },
443    { ALG_NAME_DH, DestroyDhParamsSpec }
444};
445
446static HcfFreeParamsAsyKeySpec FindAsyKeySpecFreeAbility(HcfAsyKeyParamsSpec *spec)
447{
448    for (uint32_t i = 0; i < sizeof(g_asyKeyFreeAbility) / sizeof(g_asyKeyFreeAbility[0]); i++) {
449        if (strcmp(spec->algName, g_asyKeyFreeAbility[i].algo) == 0) {
450            return g_asyKeyFreeAbility[i].createFreeFunc;
451        }
452    }
453    LOGE("No matching key params spec alg name! [Algo]: %s", spec->algName);
454    return NULL;
455}
456
457void FreeAsyKeySpec(HcfAsyKeyParamsSpec *spec)
458{
459    if (spec == NULL || spec->algName == NULL) {
460        LOGE("Invalid input parameter.");
461        return;
462    }
463    HcfFreeParamsAsyKeySpec createFreeFunc = FindAsyKeySpecFreeAbility(spec);
464    if (createFreeFunc != NULL) {
465        createFreeFunc(spec);
466    } else {
467        LOGE("create freeFunc failed.");
468    }
469}
470
471void DestroySm2CipherTextSpec(Sm2CipherTextSpec *spec)
472{
473    if (spec == NULL) {
474        return;
475    }
476    HcfFree(spec->xCoordinate.data);
477    spec->xCoordinate.data = NULL;
478    HcfFree(spec->yCoordinate.data);
479    spec->yCoordinate.data = NULL;
480    HcfBlobDataFree(&(spec->cipherTextData));
481    HcfBlobDataFree(&(spec->hashData));
482    HcfFree(spec);
483}
484
485