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 "dsa_openssl.h"
17 
18 #include <openssl/evp.h>
19 
20 #include "log.h"
21 #include "memory.h"
22 #include "openssl_adapter.h"
23 #include "openssl_common.h"
24 #include "openssl_class.h"
25 #include "utils.h"
26 
27 #define OPENSSL_DSA_SIGN_CLASS "OPENSSL.DSA.SIGN"
28 #define OPENSSL_DSA_VERIFY_CLASS "OPENSSL.DSA.VERIFY"
29 
30 typedef struct {
31     HcfSignSpi base;
32 
33     const EVP_MD *digestAlg;
34 
35     EVP_MD_CTX *mdCtx;
36 
37     EVP_PKEY_CTX *pkeyCtx;
38 
39     CryptoStatus status;
40 } HcfSignSpiDsaOpensslImpl;
41 
42 typedef struct {
43     HcfVerifySpi base;
44 
45     const EVP_MD *digestAlg;
46 
47     EVP_MD_CTX *mdCtx;
48 
49     EVP_PKEY_CTX *pkeyCtx;
50 
51     CryptoStatus status;
52 } HcfVerifySpiDsaOpensslImpl;
53 
GetDsaSignClass(void)54 static const char *GetDsaSignClass(void)
55 {
56     return OPENSSL_DSA_SIGN_CLASS;
57 }
58 
GetDsaVerifyClass(void)59 static const char *GetDsaVerifyClass(void)
60 {
61     return OPENSSL_DSA_VERIFY_CLASS;
62 }
63 
IsSignInitInputValid(HcfSignSpi * self,HcfPriKey * privateKey)64 static bool IsSignInitInputValid(HcfSignSpi *self, HcfPriKey *privateKey)
65 {
66     if ((self == NULL) || (privateKey == NULL)) {
67         LOGE("Invalid input parameter.");
68         return false;
69     }
70     if ((!HcfIsClassMatch((HcfObjectBase *)self, GetDsaSignClass())) ||
71         (!HcfIsClassMatch((HcfObjectBase *)privateKey, OPENSSL_DSA_PRIKEY_CLASS))) {
72         return false;
73     }
74     HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self;
75     if (impl->status != UNINITIALIZED) {
76         LOGE("Repeated initialization is not allowed.");
77         return false;
78     }
79     return true;
80 }
81 
IsVerifyInitInputValid(HcfVerifySpi * self,HcfPubKey * publicKey)82 static bool IsVerifyInitInputValid(HcfVerifySpi *self, HcfPubKey *publicKey)
83 {
84     if ((self == NULL) || (publicKey == NULL)) {
85         LOGE("Invalid input parameter.");
86         return false;
87     }
88     if ((!HcfIsClassMatch((HcfObjectBase *)self, GetDsaVerifyClass())) ||
89         (!HcfIsClassMatch((HcfObjectBase *)publicKey, OPENSSL_DSA_PUBKEY_CLASS))) {
90         return false;
91     }
92     HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self;
93     if (impl->status != UNINITIALIZED) {
94         LOGE("Repeated initialization is not allowed.");
95         return false;
96     }
97     return true;
98 }
99 
IsSignDoFinalInputValid(HcfSignSpi * self,HcfBlob * returnSignatureData)100 static bool IsSignDoFinalInputValid(HcfSignSpi *self, HcfBlob *returnSignatureData)
101 {
102     if ((self == NULL) || (returnSignatureData == NULL)) {
103         LOGE("Invalid input parameter.");
104         return false;
105     }
106     if (!HcfIsClassMatch((HcfObjectBase *)self, GetDsaSignClass())) {
107         return false;
108     }
109     return true;
110 }
111 
IsVerifyDoFinalInputValid(HcfVerifySpi * self,HcfBlob * signatureData)112 static bool IsVerifyDoFinalInputValid(HcfVerifySpi *self, HcfBlob *signatureData)
113 {
114     if ((self == NULL) || (!HcfIsBlobValid(signatureData))) {
115         LOGE("Invalid input parameter.");
116         return false;
117     }
118     if (!HcfIsClassMatch((HcfObjectBase *)self, GetDsaVerifyClass())) {
119         return false;
120     }
121     return true;
122 }
123 
DestroyDsaSign(HcfObjectBase * self)124 static void DestroyDsaSign(HcfObjectBase *self)
125 {
126     if (self == NULL) {
127         return;
128     }
129 
130     if (!HcfIsClassMatch(self, GetDsaSignClass())) {
131         return;
132     }
133     HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self;
134     if (impl->mdCtx != NULL) {
135         OpensslEvpMdCtxFree(impl->mdCtx);
136         impl->mdCtx = NULL;
137     }
138     if (impl->pkeyCtx != NULL) {
139         OpensslEvpPkeyCtxFree(impl->pkeyCtx);
140         impl->pkeyCtx = NULL;
141     }
142     HcfFree(impl);
143 }
144 
DestroyDsaVerify(HcfObjectBase * self)145 static void DestroyDsaVerify(HcfObjectBase *self)
146 {
147     if (self == NULL) {
148         return;
149     }
150     if (!HcfIsClassMatch(self, GetDsaVerifyClass())) {
151         return;
152     }
153     HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self;
154     if (impl->mdCtx != NULL) {
155         OpensslEvpMdCtxFree(impl->mdCtx);
156         impl->mdCtx = NULL;
157     }
158     if (impl->pkeyCtx != NULL) {
159         OpensslEvpPkeyCtxFree(impl->pkeyCtx);
160         impl->pkeyCtx = NULL;
161     }
162     HcfFree(impl);
163 }
164 
CreateDsaEvpKeyByDsa(HcfKey * key,bool isSign)165 static EVP_PKEY *CreateDsaEvpKeyByDsa(HcfKey *key, bool isSign)
166 {
167     EVP_PKEY *pKey = OpensslEvpPkeyNew();
168     if (pKey == NULL) {
169         LOGD("[error] EVP_PKEY_new fail");
170         HcfPrintOpensslError();
171         return NULL;
172     }
173     DSA *dsa = isSign ? ((HcfOpensslDsaPriKey *)key)->sk : ((HcfOpensslDsaPubKey *)key)->pk;
174     if (dsa == NULL) {
175         LOGD("[error] dsa has been cleared");
176         EVP_PKEY_free(pKey);
177         return NULL;
178     }
179     if (OpensslEvpPkeySet1Dsa(pKey, dsa) != HCF_OPENSSL_SUCCESS) {
180         LOGD("[error] EVP_PKEY_set1_DSA fail");
181         HcfPrintOpensslError();
182         EVP_PKEY_free(pKey);
183         return NULL;
184     }
185     return pKey;
186 }
187 
EngineDsaSignInit(HcfSignSpi * self,HcfParamsSpec * params,HcfPriKey * privateKey)188 static HcfResult EngineDsaSignInit(HcfSignSpi *self, HcfParamsSpec *params, HcfPriKey *privateKey)
189 {
190     (void)params;
191     if (!IsSignInitInputValid(self, privateKey)) {
192         return HCF_INVALID_PARAMS;
193     }
194     EVP_PKEY *pKey = CreateDsaEvpKeyByDsa((HcfKey *)privateKey, true);
195     if (pKey == NULL) {
196         LOGE("Create DSA evp key failed!");
197         return HCF_ERR_CRYPTO_OPERATION;
198     }
199     HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self;
200     if (OpensslEvpDigestSignInit(impl->mdCtx, NULL, impl->digestAlg, NULL, pKey) != HCF_OPENSSL_SUCCESS) {
201         HcfPrintOpensslError();
202         OpensslEvpPkeyFree(pKey);
203         return HCF_ERR_CRYPTO_OPERATION;
204     }
205 
206     OpensslEvpPkeyFree(pKey);
207     impl->status = INITIALIZED;
208     return HCF_SUCCESS;
209 }
210 
EngineDsaSignWithoutDigestInit(HcfSignSpi * self,HcfParamsSpec * params,HcfPriKey * privateKey)211 static HcfResult EngineDsaSignWithoutDigestInit(HcfSignSpi *self, HcfParamsSpec *params, HcfPriKey *privateKey)
212 {
213     (void)params;
214     if (!IsSignInitInputValid(self, privateKey)) {
215         return HCF_INVALID_PARAMS;
216     }
217     EVP_PKEY *pKey = CreateDsaEvpKeyByDsa((HcfKey *)privateKey, true);
218     if (pKey == NULL) {
219         LOGD("[error] Create DSA evp key failed!");
220         return HCF_ERR_CRYPTO_OPERATION;
221     }
222     HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self;
223 
224     impl->pkeyCtx = OpensslEvpPkeyCtxNew(pKey, NULL);
225     if (impl->pkeyCtx == NULL) {
226         HcfPrintOpensslError();
227         OpensslEvpPkeyFree(pKey);
228         return HCF_ERR_CRYPTO_OPERATION;
229     }
230     if (OpensslEvpPkeySignInit(impl->pkeyCtx) != HCF_OPENSSL_SUCCESS) {
231         HcfPrintOpensslError();
232         OpensslEvpPkeyFree(pKey);
233         OpensslEvpPkeyCtxFree(impl->pkeyCtx);
234         impl->pkeyCtx = NULL;
235         return HCF_ERR_CRYPTO_OPERATION;
236     }
237     OpensslEvpPkeyFree(pKey);
238     impl->status = READY;
239     return HCF_SUCCESS;
240 }
241 
EngineDsaVerifyInit(HcfVerifySpi * self,HcfParamsSpec * params,HcfPubKey * publicKey)242 static HcfResult EngineDsaVerifyInit(HcfVerifySpi *self, HcfParamsSpec *params, HcfPubKey *publicKey)
243 {
244     (void)params;
245     if (!IsVerifyInitInputValid(self, publicKey)) {
246         return HCF_INVALID_PARAMS;
247     }
248     HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self;
249     EVP_PKEY *pKey = CreateDsaEvpKeyByDsa((HcfKey *)publicKey, false);
250     if (pKey == NULL) {
251         LOGD("[error] Create DSA evp key failed!");
252         return HCF_ERR_CRYPTO_OPERATION;
253     }
254     if (OpensslEvpDigestVerifyInit(impl->mdCtx, NULL, impl->digestAlg, NULL, pKey) != HCF_OPENSSL_SUCCESS) {
255         HcfPrintOpensslError();
256         OpensslEvpPkeyFree(pKey);
257         return HCF_ERR_CRYPTO_OPERATION;
258     }
259 
260     OpensslEvpPkeyFree(pKey);
261     impl->status = INITIALIZED;
262     return HCF_SUCCESS;
263 }
264 
EngineDsaVerifyWithoutDigestInit(HcfVerifySpi * self,HcfParamsSpec * params,HcfPubKey * publicKey)265 static HcfResult EngineDsaVerifyWithoutDigestInit(HcfVerifySpi *self, HcfParamsSpec *params, HcfPubKey *publicKey)
266 {
267     (void)params;
268     if (!IsVerifyInitInputValid(self, publicKey)) {
269         return HCF_INVALID_PARAMS;
270     }
271     HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self;
272     EVP_PKEY *pKey = CreateDsaEvpKeyByDsa((HcfKey *)publicKey, false);
273     if (pKey == NULL) {
274         LOGD("[error] Create dsa evp key failed!");
275         return HCF_ERR_CRYPTO_OPERATION;
276     }
277     impl->pkeyCtx = OpensslEvpPkeyCtxNew(pKey, NULL);
278     if (impl->pkeyCtx == NULL) {
279         HcfPrintOpensslError();
280         OpensslEvpPkeyFree(pKey);
281         return HCF_ERR_CRYPTO_OPERATION;
282     }
283     if (OpensslEvpPkeyVerifyInit(impl->pkeyCtx) != HCF_OPENSSL_SUCCESS) {
284         HcfPrintOpensslError();
285         OpensslEvpPkeyFree(pKey);
286         OpensslEvpPkeyCtxFree(impl->pkeyCtx);
287         impl->pkeyCtx = NULL;
288         return HCF_ERR_CRYPTO_OPERATION;
289     }
290     OpensslEvpPkeyFree(pKey);
291     impl->status = READY;
292     return HCF_SUCCESS;
293 }
294 
EngineDsaSignUpdate(HcfSignSpi * self,HcfBlob * data)295 static HcfResult EngineDsaSignUpdate(HcfSignSpi *self, HcfBlob *data)
296 {
297     if ((self == NULL) || (!HcfIsBlobValid(data))) {
298         LOGE("Invalid input parameter.");
299         return HCF_INVALID_PARAMS;
300     }
301     if (!HcfIsClassMatch((HcfObjectBase *)self, GetDsaSignClass())) {
302         return HCF_INVALID_PARAMS;
303     }
304     HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self;
305     if (impl->status == UNINITIALIZED) {
306         LOGE("Sign object has not been initialized.");
307         return HCF_INVALID_PARAMS;
308     }
309     if (OpensslEvpDigestSignUpdate(impl->mdCtx, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
310         HcfPrintOpensslError();
311         return HCF_ERR_CRYPTO_OPERATION;
312     }
313     impl->status = READY;
314     return HCF_SUCCESS;
315 }
316 
EngineDsaSignWithoutDigestUpdate(HcfSignSpi * self,HcfBlob * data)317 static HcfResult EngineDsaSignWithoutDigestUpdate(HcfSignSpi *self, HcfBlob *data)
318 {
319     (void)self;
320     (void)data;
321     return HCF_ERR_CRYPTO_OPERATION;
322 }
323 
EngineDsaVerifyUpdate(HcfVerifySpi * self,HcfBlob * data)324 static HcfResult EngineDsaVerifyUpdate(HcfVerifySpi *self, HcfBlob *data)
325 {
326     if ((self == NULL) || (!HcfIsBlobValid(data))) {
327         LOGE("Invalid input parameter.");
328         return HCF_INVALID_PARAMS;
329     }
330     if (!HcfIsClassMatch((HcfObjectBase *)self, GetDsaVerifyClass())) {
331         return HCF_INVALID_PARAMS;
332     }
333     HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self;
334     if (impl->status == UNINITIALIZED) {
335         LOGE("Verify object has not been initialized.");
336         return HCF_INVALID_PARAMS;
337     }
338 
339     if (OpensslEvpDigestVerifyUpdate(impl->mdCtx, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
340         HcfPrintOpensslError();
341         return HCF_ERR_CRYPTO_OPERATION;
342     }
343     impl->status = READY;
344     return HCF_SUCCESS;
345 }
346 
EngineDsaVerifyWithoutDigestUpdate(HcfVerifySpi * self,HcfBlob * data)347 static HcfResult EngineDsaVerifyWithoutDigestUpdate(HcfVerifySpi *self, HcfBlob *data)
348 {
349     (void)self;
350     (void)data;
351     return HCF_ERR_CRYPTO_OPERATION;
352 }
353 
EngineDsaSignDoFinal(HcfSignSpi * self,HcfBlob * data,HcfBlob * returnSignatureData)354 static HcfResult EngineDsaSignDoFinal(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSignatureData)
355 {
356     if (!IsSignDoFinalInputValid(self, returnSignatureData)) {
357         return HCF_INVALID_PARAMS;
358     }
359     HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self;
360     if (HcfIsBlobValid(data)) {
361         if (OpensslEvpDigestSignUpdate(impl->mdCtx, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
362             HcfPrintOpensslError();
363             return HCF_ERR_CRYPTO_OPERATION;
364         }
365         impl->status = READY;
366     }
367     if (impl->status != READY) {
368         LOGE("The message has not been transferred.");
369         return HCF_INVALID_PARAMS;
370     }
371     size_t maxLen;
372     if (OpensslEvpDigestSignFinal(impl->mdCtx, NULL, &maxLen) != HCF_OPENSSL_SUCCESS) {
373         HcfPrintOpensslError();
374         return HCF_ERR_CRYPTO_OPERATION;
375     }
376     uint8_t *signatureData = (uint8_t *)HcfMalloc(maxLen, 0);
377     if (signatureData == NULL) {
378         LOGE("Failed to allocate signatureData memory!");
379         return HCF_ERR_MALLOC;
380     }
381 
382     if (OpensslEvpDigestSignFinal(impl->mdCtx, signatureData, &maxLen) != HCF_OPENSSL_SUCCESS) {
383         HcfPrintOpensslError();
384         HcfFree(signatureData);
385         return HCF_ERR_CRYPTO_OPERATION;
386     }
387 
388     returnSignatureData->data = signatureData;
389     returnSignatureData->len = (uint32_t)maxLen;
390     return HCF_SUCCESS;
391 }
392 
EngineDsaSignWithoutDigestDoFinal(HcfSignSpi * self,HcfBlob * data,HcfBlob * returnSignatureData)393 static HcfResult EngineDsaSignWithoutDigestDoFinal(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSignatureData)
394 {
395     if (!IsSignDoFinalInputValid(self, returnSignatureData)) {
396         return HCF_INVALID_PARAMS;
397     }
398     if (!HcfIsBlobValid(data)) {
399         LOGE("Src data is invalid.");
400         return HCF_INVALID_PARAMS;
401     }
402     HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self;
403     if (impl->status != READY) {
404         LOGE("Not init yet.");
405         return HCF_INVALID_PARAMS;
406     }
407     size_t maxLen;
408     if (OpensslEvpPkeySign(impl->pkeyCtx, NULL, &maxLen,
409         (const unsigned char *)data->data, data->len) != HCF_OPENSSL_SUCCESS) {
410         HcfPrintOpensslError();
411         return HCF_ERR_CRYPTO_OPERATION;
412     }
413     uint8_t *signatureData = (uint8_t *)HcfMalloc(maxLen, 0);
414     if (signatureData == NULL) {
415         LOGE("Failed to allocate signatureData memory!");
416         return HCF_ERR_MALLOC;
417     }
418     size_t actualLen = maxLen;
419     if (OpensslEvpPkeySign(impl->pkeyCtx, signatureData, &actualLen,
420         (const unsigned char *)data->data, data->len) != HCF_OPENSSL_SUCCESS) {
421         HcfPrintOpensslError();
422         HcfFree(signatureData);
423         return HCF_ERR_CRYPTO_OPERATION;
424     }
425     if (actualLen > maxLen) {
426         LOGD("[error] Signature data too long.");
427         HcfFree(signatureData);
428         return HCF_ERR_CRYPTO_OPERATION;
429     }
430 
431     returnSignatureData->data = signatureData;
432     returnSignatureData->len = (uint32_t)actualLen;
433     return HCF_SUCCESS;
434 }
435 
EngineDsaVerifyDoFinal(HcfVerifySpi * self,HcfBlob * data,HcfBlob * signatureData)436 static bool EngineDsaVerifyDoFinal(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureData)
437 {
438     if (!IsVerifyDoFinalInputValid(self, signatureData)) {
439         return false;
440     }
441 
442     HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self;
443     if (HcfIsBlobValid(data)) {
444         if (OpensslEvpDigestVerifyUpdate(impl->mdCtx, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
445             LOGD("[error] Openssl update failed.");
446             HcfPrintOpensslError();
447             return false;
448         }
449         impl->status = READY;
450     }
451     if (impl->status != READY) {
452         LOGE("The message has not been transferred.");
453         return false;
454     }
455 
456     if (OpensslEvpDigestVerifyFinal(impl->mdCtx, signatureData->data, signatureData->len) != HCF_OPENSSL_SUCCESS) {
457         HcfPrintOpensslError();
458         return false;
459     }
460     return true;
461 }
462 
EngineDsaVerifyWithoutDigestDoFinal(HcfVerifySpi * self,HcfBlob * data,HcfBlob * signatureData)463 static bool EngineDsaVerifyWithoutDigestDoFinal(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureData)
464 {
465     if (!IsVerifyDoFinalInputValid(self, signatureData)) {
466         return false;
467     }
468     if (!HcfIsBlobValid(data)) {
469         LOGE("Src data is invalid.");
470         return false;
471     }
472     HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self;
473     if (impl->status != READY) {
474         LOGE("Not init yet.");
475         return false;
476     }
477 
478     if (OpensslEvpPkeyVerify(impl->pkeyCtx, signatureData->data,
479         signatureData->len, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
480         HcfPrintOpensslError();
481         return false;
482     }
483     return true;
484 }
485 
EngineSetSignDsaSpecInt(HcfSignSpi * self,SignSpecItem item,int32_t saltLen)486 static HcfResult EngineSetSignDsaSpecInt(HcfSignSpi *self, SignSpecItem item, int32_t saltLen)
487 {
488     (void)self;
489     (void)item;
490     (void)saltLen;
491     return HCF_NOT_SUPPORT;
492 }
493 
EngineSetVerifyDsaSpecInt(HcfVerifySpi * self,SignSpecItem item,int32_t saltLen)494 static HcfResult EngineSetVerifyDsaSpecInt(HcfVerifySpi *self, SignSpecItem item, int32_t saltLen)
495 {
496     (void)self;
497     (void)item;
498     (void)saltLen;
499     return HCF_NOT_SUPPORT;
500 }
501 
EngineGetSignDsaSpecInt(HcfSignSpi * self,SignSpecItem item,int32_t * returnInt)502 static HcfResult EngineGetSignDsaSpecInt(HcfSignSpi *self, SignSpecItem item, int32_t *returnInt)
503 {
504     (void)self;
505     (void)item;
506     (void)returnInt;
507     return HCF_NOT_SUPPORT;
508 }
509 
EngineGetVerifyDsaSpecInt(HcfVerifySpi * self,SignSpecItem item,int32_t * returnInt)510 static HcfResult EngineGetVerifyDsaSpecInt(HcfVerifySpi *self, SignSpecItem item, int32_t *returnInt)
511 {
512     (void)self;
513     (void)item;
514     (void)returnInt;
515     return HCF_NOT_SUPPORT;
516 }
517 
EngineGetSignDsaSpecString(HcfSignSpi * self,SignSpecItem item,char ** returnString)518 static HcfResult EngineGetSignDsaSpecString(HcfSignSpi *self, SignSpecItem item, char **returnString)
519 {
520     (void)self;
521     (void)item;
522     (void)returnString;
523     return HCF_NOT_SUPPORT;
524 }
525 
EngineSetSignDsaSpecUint8Array(HcfSignSpi * self,SignSpecItem item,HcfBlob blob)526 static HcfResult EngineSetSignDsaSpecUint8Array(HcfSignSpi *self, SignSpecItem item, HcfBlob blob)
527 {
528     (void)self;
529     (void)item;
530     (void)blob;
531     return HCF_NOT_SUPPORT;
532 }
533 
EngineGetVerifyDsaSpecString(HcfVerifySpi * self,SignSpecItem item,char ** returnString)534 static HcfResult EngineGetVerifyDsaSpecString(HcfVerifySpi *self, SignSpecItem item, char **returnString)
535 {
536     (void)self;
537     (void)item;
538     (void)returnString;
539     return HCF_NOT_SUPPORT;
540 }
541 
EngineSetVerifyDsaSpecUint8Array(HcfVerifySpi * self,SignSpecItem item,HcfBlob blob)542 static HcfResult EngineSetVerifyDsaSpecUint8Array(HcfVerifySpi *self, SignSpecItem item, HcfBlob blob)
543 {
544     (void)self;
545     (void)item;
546     (void)blob;
547     return HCF_NOT_SUPPORT;
548 }
549 
HcfSignSpiDsaCreate(HcfSignatureParams * params,HcfSignSpi ** returnObj)550 HcfResult HcfSignSpiDsaCreate(HcfSignatureParams *params, HcfSignSpi **returnObj)
551 {
552     if ((params == NULL) || (returnObj == NULL)) {
553         LOGE("Invalid input parameter.");
554         return HCF_INVALID_PARAMS;
555     }
556 
557     HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)HcfMalloc(sizeof(HcfSignSpiDsaOpensslImpl), 0);
558     if (impl == NULL) {
559         LOGE("Failed to allocate impl memroy!");
560         return HCF_ERR_MALLOC;
561     }
562 
563     EVP_MD *digestAlg = NULL;
564 
565     if (params->md == HCF_OPENSSL_DIGEST_NONE) {
566         impl->base.engineInit = EngineDsaSignWithoutDigestInit;
567         impl->base.engineUpdate = EngineDsaSignWithoutDigestUpdate;
568         impl->base.engineSign = EngineDsaSignWithoutDigestDoFinal;
569     } else {
570         HcfResult ret = GetOpensslDigestAlg(params->md, &digestAlg);
571         if (ret != HCF_SUCCESS) {
572             HcfFree(impl);
573             return HCF_INVALID_PARAMS;
574         }
575         impl->base.engineInit = EngineDsaSignInit;
576         impl->base.engineUpdate = EngineDsaSignUpdate;
577         impl->base.engineSign = EngineDsaSignDoFinal;
578         impl->mdCtx = OpensslEvpMdCtxNew();
579         if (impl->mdCtx == NULL) {
580             LOGE("Failed to allocate ctx memory!");
581             HcfFree(impl);
582             return HCF_ERR_MALLOC;
583         }
584     }
585     impl->base.base.getClass = GetDsaSignClass;
586     impl->base.base.destroy = DestroyDsaSign;
587     impl->base.engineSetSignSpecInt = EngineSetSignDsaSpecInt;
588     impl->base.engineGetSignSpecInt = EngineGetSignDsaSpecInt;
589     impl->base.engineGetSignSpecString = EngineGetSignDsaSpecString;
590     impl->base.engineSetSignSpecUint8Array = EngineSetSignDsaSpecUint8Array;
591     impl->status = UNINITIALIZED;
592     impl->digestAlg = digestAlg;
593     *returnObj = (HcfSignSpi *)impl;
594     return HCF_SUCCESS;
595 }
596 
HcfVerifySpiDsaCreate(HcfSignatureParams * params,HcfVerifySpi ** returnObj)597 HcfResult HcfVerifySpiDsaCreate(HcfSignatureParams *params, HcfVerifySpi **returnObj)
598 {
599     if ((params == NULL) || (returnObj == NULL)) {
600         LOGE("Invalid input parameter.");
601         return HCF_INVALID_PARAMS;
602     }
603 
604     HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)HcfMalloc(sizeof(HcfVerifySpiDsaOpensslImpl), 0);
605     if (impl == NULL) {
606         LOGE("Failed to allocate impl memroy!");
607         return HCF_ERR_MALLOC;
608     }
609 
610     EVP_MD *digestAlg = NULL;
611     if (params->md == HCF_OPENSSL_DIGEST_NONE) {
612         impl->base.engineInit = EngineDsaVerifyWithoutDigestInit;
613         impl->base.engineUpdate = EngineDsaVerifyWithoutDigestUpdate;
614         impl->base.engineVerify = EngineDsaVerifyWithoutDigestDoFinal;
615     } else {
616         HcfResult ret = GetOpensslDigestAlg(params->md, &digestAlg);
617         if (ret != HCF_SUCCESS) {
618             HcfFree(impl);
619             return HCF_INVALID_PARAMS;
620         }
621         impl->base.engineInit = EngineDsaVerifyInit;
622         impl->base.engineUpdate = EngineDsaVerifyUpdate;
623         impl->base.engineVerify = EngineDsaVerifyDoFinal;
624         impl->mdCtx = OpensslEvpMdCtxNew();
625         if (impl->mdCtx == NULL) {
626             LOGE("Failed to allocate ctx memory!");
627             HcfFree(impl);
628             return HCF_ERR_MALLOC;
629         }
630     }
631     impl->base.base.getClass = GetDsaVerifyClass;
632     impl->base.base.destroy = DestroyDsaVerify;
633     impl->base.engineSetVerifySpecInt = EngineSetVerifyDsaSpecInt;
634     impl->base.engineGetVerifySpecInt = EngineGetVerifyDsaSpecInt;
635     impl->base.engineGetVerifySpecString = EngineGetVerifyDsaSpecString;
636     impl->base.engineSetVerifySpecUint8Array = EngineSetVerifyDsaSpecUint8Array;
637     impl->digestAlg = digestAlg;
638     impl->status = UNINITIALIZED;
639 
640     *returnObj = (HcfVerifySpi *)impl;
641     return HCF_SUCCESS;
642 }