• 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 "sm2_openssl.h"
17 
18 #include <openssl/bio.h>
19 #include <openssl/err.h>
20 
21 #include "securec.h"
22 
23 #include "algorithm_parameter.h"
24 #include "openssl_adapter.h"
25 #include "openssl_class.h"
26 #include "openssl_common.h"
27 #include "log.h"
28 #include "memory.h"
29 #include "utils.h"
30 
31 #define OPENSSL_SM2_SIGN_CLASS "OPENSSL.SM2.SIGN"
32 #define OPENSSL_SM2_VERIFY_CLASS "OPENSSL.SM2.VERIFY"
33 
34 typedef struct {
35     HcfSignSpi base;
36 
37     HcfBlob userId;
38 
39     const EVP_MD *digestAlg;
40 
41     EVP_MD_CTX *mdCtx;
42 
43     CryptoStatus status;
44 } HcfSignSpiSm2OpensslImpl;
45 
46 typedef struct {
47     HcfVerifySpi base;
48 
49     HcfBlob userId;
50 
51     const EVP_MD *digestAlg;
52 
53     EVP_MD_CTX *mdCtx;
54 
55     CryptoStatus status;
56 } HcfVerifySpiSm2OpensslImpl;
57 
IsDigestAlgValid(uint32_t alg)58 static bool IsDigestAlgValid(uint32_t alg)
59 {
60     if (alg == HCF_OPENSSL_DIGEST_SM3) {
61         return true;
62     } else {
63         LOGE("Invalid digest num!");
64         return false;
65     }
66 }
67 
68 // export interfaces
GetSm2SignClass(void)69 static const char *GetSm2SignClass(void)
70 {
71     return OPENSSL_SM2_SIGN_CLASS;
72 }
73 
GetSm2VerifyClass(void)74 static const char *GetSm2VerifyClass(void)
75 {
76     return OPENSSL_SM2_VERIFY_CLASS;
77 }
78 
DestroySm2Sign(HcfObjectBase * self)79 static void DestroySm2Sign(HcfObjectBase *self)
80 {
81     if (self == NULL) {
82         LOGE("Class is null.");
83         return;
84     }
85     if (!HcfIsClassMatch(self, self->getClass())) {
86         LOGE("Class not match.");
87         return;
88     }
89     HcfSignSpiSm2OpensslImpl *impl = (HcfSignSpiSm2OpensslImpl *)self;
90     impl->digestAlg = NULL;
91     if (impl->mdCtx != NULL) {
92         OpensslEvpPkeyCtxFree(OpensslEvpMdCtxGetPkeyCtx(impl->mdCtx));
93         OpensslEvpMdCtxFree(impl->mdCtx);
94         impl->mdCtx = NULL;
95     }
96     HcfFree(impl->userId.data);
97     impl->userId.data = NULL;
98     HcfFree(impl);
99 }
100 
DestroySm2Verify(HcfObjectBase * self)101 static void DestroySm2Verify(HcfObjectBase *self)
102 {
103     if (self == NULL) {
104         LOGE("Class is null.");
105         return;
106     }
107     if (!HcfIsClassMatch(self, self->getClass())) {
108         LOGE("Class not match.");
109         return;
110     }
111     HcfVerifySpiSm2OpensslImpl *impl = (HcfVerifySpiSm2OpensslImpl *)self;
112     impl->digestAlg = NULL;
113     if (impl->mdCtx != NULL) {
114         OpensslEvpPkeyCtxFree(OpensslEvpMdCtxGetPkeyCtx(impl->mdCtx));
115         OpensslEvpMdCtxFree(impl->mdCtx);
116         impl->mdCtx = NULL;
117     }
118     HcfFree(impl->userId.data);
119     impl->userId.data = NULL;
120     HcfFree(impl);
121 }
SetUserIdFromBlob(HcfBlob userId,EVP_MD_CTX * mdCtx)122 static HcfResult SetUserIdFromBlob(HcfBlob userId, EVP_MD_CTX *mdCtx)
123 {
124     EVP_PKEY_CTX *pKeyCtx = OpensslEvpMdCtxGetPkeyCtx(mdCtx);
125     if (pKeyCtx == NULL) {
126         LOGD("[error] get pKey ctx fail.");
127         HcfPrintOpensslError();
128         return HCF_ERR_CRYPTO_OPERATION;
129     }
130     // If userId is NULL or len is 0, the userId will be cleared.
131     if (userId.data == NULL || userId.len == 0) {
132         if (OpensslEvpPkeyCtxSet1Id(pKeyCtx, NULL, 0) != HCF_OPENSSL_SUCCESS) {
133             LOGD("[error] Openssl Set userId fail");
134             HcfPrintOpensslError();
135             return HCF_ERR_CRYPTO_OPERATION;
136         }
137         OpensslEvpMdCtxSetPkeyCtx(mdCtx, pKeyCtx);
138         return HCF_SUCCESS;
139     }
140     if (OpensslEvpPkeyCtxSet1Id(pKeyCtx, (const void*)userId.data,
141         userId.len) != HCF_OPENSSL_SUCCESS) {
142         LOGD("[error] Set sm2 user id fail.");
143         HcfPrintOpensslError();
144         return HCF_ERR_CRYPTO_OPERATION;
145     }
146     OpensslEvpMdCtxSetPkeyCtx(mdCtx, pKeyCtx);
147     return HCF_SUCCESS;
148 }
149 
SetSM2Id(EVP_MD_CTX * mdCtx,EVP_PKEY * pKey,HcfBlob userId)150 static HcfResult SetSM2Id(EVP_MD_CTX *mdCtx, EVP_PKEY *pKey, HcfBlob userId)
151 {
152     EVP_PKEY_CTX *pKeyCtx = OpensslEvpPkeyCtxNew(pKey, NULL);
153     if (pKeyCtx == NULL) {
154         LOGD("[error] new EVP_PKEY_CTX fail");
155         HcfPrintOpensslError();
156         return HCF_ERR_CRYPTO_OPERATION;
157     }
158     if (OpensslEvpPkeyCtxSet1Id(pKeyCtx, (const void*)userId.data,
159         userId.len) != HCF_OPENSSL_SUCCESS) {
160         LOGD("[error] Set sm2 user id fail");
161         HcfPrintOpensslError();
162         OpensslEvpPkeyCtxFree(pKeyCtx);
163         return HCF_ERR_CRYPTO_OPERATION;
164     }
165     OpensslEvpMdCtxSetPkeyCtx(mdCtx, pKeyCtx);
166     return HCF_SUCCESS;
167 }
168 
IsSm2SignInitInputValid(HcfSignSpi * self,HcfPriKey * privateKey)169 static bool IsSm2SignInitInputValid(HcfSignSpi *self, HcfPriKey *privateKey)
170 {
171     if ((self == NULL) || (privateKey == NULL)) {
172         LOGE("Invalid input parameter.");
173         return false;
174     }
175     if ((!HcfIsClassMatch((HcfObjectBase *)self, self->base.getClass())) ||
176         (!HcfIsClassMatch((HcfObjectBase *)privateKey, HCF_OPENSSL_SM2_PRI_KEY_CLASS))) {
177         LOGE("Class not match.");
178         return false;
179     }
180     HcfSignSpiSm2OpensslImpl *impl = (HcfSignSpiSm2OpensslImpl *)self;
181     if (impl->status != UNINITIALIZED) {
182         LOGE("Repeated initialization is not allowed.");
183         return false;
184     }
185     return true;
186 }
187 
EngineSignInit(HcfSignSpi * self,HcfParamsSpec * params,HcfPriKey * privateKey)188 static HcfResult EngineSignInit(HcfSignSpi *self, HcfParamsSpec *params, HcfPriKey *privateKey)
189 {
190     (void)params;
191     if (!IsSm2SignInitInputValid(self, privateKey)) {
192         return HCF_INVALID_PARAMS;
193     }
194 
195     EC_KEY *ecKey = OpensslEcKeyDup(((HcfOpensslSm2PriKey *)privateKey)->ecKey);
196     if (ecKey == NULL) {
197         HcfPrintOpensslError();
198         LOGD("[error] Dup ecKey failed.");
199         return HCF_ERR_CRYPTO_OPERATION;
200     }
201     EVP_PKEY *pKey = OpensslEvpPkeyNew();
202     if (pKey == NULL) {
203         HcfPrintOpensslError();
204         LOGD("[error] New pKey failed.");
205         OpensslEcKeyFree(ecKey);
206         return HCF_ERR_CRYPTO_OPERATION;
207     }
208     if (OpensslEvpPkeyAssignEcKey(pKey, ecKey) != HCF_OPENSSL_SUCCESS) {
209         HcfPrintOpensslError();
210         LOGD("[error] EVP_PKEY_assign_EC_KEY failed.");
211         OpensslEcKeyFree(ecKey);
212         OpensslEvpPkeyFree(pKey);
213         return HCF_ERR_CRYPTO_OPERATION;
214     }
215 
216     HcfSignSpiSm2OpensslImpl *impl = (HcfSignSpiSm2OpensslImpl *)self;
217     if (SetSM2Id(impl->mdCtx, pKey, impl->userId) != HCF_SUCCESS) {
218         OpensslEvpPkeyFree(pKey);
219         LOGD("[error] Set sm2 user id failed.");
220         return HCF_ERR_CRYPTO_OPERATION;
221     }
222     if (OpensslEvpDigestSignInit(impl->mdCtx, NULL, impl->digestAlg, NULL, pKey) != HCF_OPENSSL_SUCCESS) {
223         HcfPrintOpensslError();
224         LOGD("[error] EVP_DigestSignInit failed.");
225         OpensslEvpPkeyFree(pKey);
226         return HCF_ERR_CRYPTO_OPERATION;
227     }
228     OpensslEvpPkeyFree(pKey);
229     impl->status = INITIALIZED;
230     return HCF_SUCCESS;
231 }
232 
EngineSignUpdate(HcfSignSpi * self,HcfBlob * data)233 static HcfResult EngineSignUpdate(HcfSignSpi *self, HcfBlob *data)
234 {
235     if ((self == NULL) || (!HcfIsBlobValid(data))) {
236         LOGE("Invalid input parameter.");
237         return HCF_INVALID_PARAMS;
238     }
239     if (!HcfIsClassMatch((HcfObjectBase *)self, self->base.getClass())) {
240         LOGE("Class not match.");
241         return HCF_INVALID_PARAMS;
242     }
243     HcfSignSpiSm2OpensslImpl *impl = (HcfSignSpiSm2OpensslImpl *)self;
244     if (impl->status == UNINITIALIZED) {
245         LOGE("Sign object has not been initialized.");
246         return HCF_INVALID_PARAMS;
247     }
248     if (OpensslEvpDigestSignUpdate(impl->mdCtx, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
249         HcfPrintOpensslError();
250         LOGD("[error] EVP_DigestSignUpdate failed.");
251         return HCF_ERR_CRYPTO_OPERATION;
252     }
253     impl->status = READY;
254     return HCF_SUCCESS;
255 }
256 
EngineSignDoFinal(HcfSignSpi * self,HcfBlob * data,HcfBlob * returnSignatureData)257 static HcfResult EngineSignDoFinal(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSignatureData)
258 {
259     if ((self == NULL) || (returnSignatureData == NULL)) {
260         LOGE("Invalid input parameter.");
261         return HCF_INVALID_PARAMS;
262     }
263     if (!HcfIsClassMatch((HcfObjectBase *)self, self->base.getClass())) {
264         LOGE("Class not match.");
265         return HCF_INVALID_PARAMS;
266     }
267 
268     HcfSignSpiSm2OpensslImpl *impl = (HcfSignSpiSm2OpensslImpl *)self;
269     if (HcfIsBlobValid(data)) {
270         if (OpensslEvpDigestSignUpdate(impl->mdCtx, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
271             HcfPrintOpensslError();
272             LOGD("[error] EVP_DigestSignUpdate failed.");
273             return HCF_ERR_CRYPTO_OPERATION;
274         }
275         impl->status = READY;
276     }
277     if (impl->status != READY) {
278         LOGE("The message has not been transferred.");
279         return HCF_INVALID_PARAMS;
280     }
281     size_t maxLen;
282     if (OpensslEvpDigestSignFinal(impl->mdCtx, NULL, &maxLen) != HCF_OPENSSL_SUCCESS) {
283         HcfPrintOpensslError();
284         LOGD("[error] EVP_DigestSignFinal failed.");
285         return HCF_ERR_CRYPTO_OPERATION;
286     }
287     uint8_t *outData = (uint8_t *)HcfMalloc(maxLen, 0);
288     if (outData == NULL) {
289         LOGE("Failed to allocate outData memory!");
290         return HCF_ERR_MALLOC;
291     }
292 
293     if (OpensslEvpDigestSignFinal(impl->mdCtx, outData, &maxLen) != HCF_OPENSSL_SUCCESS) {
294         HcfPrintOpensslError();
295         LOGD("[error] EVP_DigestSignFinal failed.");
296         HcfFree(outData);
297         outData = NULL;
298         return HCF_ERR_CRYPTO_OPERATION;
299     }
300 
301     returnSignatureData->data = outData;
302     returnSignatureData->len = (uint32_t)maxLen;
303     return HCF_SUCCESS;
304 }
305 
IsSm2VerifyInitInputValid(HcfVerifySpi * self,HcfPubKey * publicKey)306 static bool IsSm2VerifyInitInputValid(HcfVerifySpi *self, HcfPubKey *publicKey)
307 {
308     if ((self == NULL) || (publicKey == NULL)) {
309         LOGE("Invalid input parameter.");
310         return false;
311     }
312     if ((!HcfIsClassMatch((HcfObjectBase *)self, self->base.getClass())) ||
313         (!HcfIsClassMatch((HcfObjectBase *)publicKey, HCF_OPENSSL_SM2_PUB_KEY_CLASS))) {
314         LOGE("Class not match.");
315         return false;
316     }
317 
318     HcfVerifySpiSm2OpensslImpl *impl = (HcfVerifySpiSm2OpensslImpl *)self;
319     if (impl->status != UNINITIALIZED) {
320         LOGE("Repeated initialization is not allowed.");
321         return false;
322     }
323     return true;
324 }
325 
EngineVerifyInit(HcfVerifySpi * self,HcfParamsSpec * params,HcfPubKey * publicKey)326 static HcfResult EngineVerifyInit(HcfVerifySpi *self, HcfParamsSpec *params, HcfPubKey *publicKey)
327 {
328     (void)params;
329     if (!IsSm2VerifyInitInputValid(self, publicKey)) {
330         return HCF_INVALID_PARAMS;
331     }
332 
333     EC_KEY *ecKey = OpensslEcKeyDup(((HcfOpensslSm2PubKey *)publicKey)->ecKey);
334     if (ecKey == NULL) {
335         HcfPrintOpensslError();
336         LOGD("[error] Dup ecKey failed.");
337         return HCF_ERR_CRYPTO_OPERATION;
338     }
339     EVP_PKEY *pKey = OpensslEvpPkeyNew();
340     if (pKey == NULL) {
341         HcfPrintOpensslError();
342         LOGD("[error] New pKey failed.");
343         OpensslEcKeyFree(ecKey);
344         return HCF_ERR_CRYPTO_OPERATION;
345     }
346     if (OpensslEvpPkeyAssignEcKey(pKey, ecKey) != HCF_OPENSSL_SUCCESS) {
347         HcfPrintOpensslError();
348         LOGD("[error] EVP_PKEY_assign_EC_KEY failed.");
349         OpensslEcKeyFree(ecKey);
350         OpensslEvpPkeyFree(pKey);
351         return HCF_ERR_CRYPTO_OPERATION;
352     }
353     HcfVerifySpiSm2OpensslImpl *impl = (HcfVerifySpiSm2OpensslImpl *)self;
354     if (SetSM2Id(impl->mdCtx, pKey, impl->userId) != HCF_SUCCESS) {
355         LOGD("[error] Set sm2 user id failed.");
356         OpensslEvpPkeyFree(pKey);
357         return HCF_ERR_CRYPTO_OPERATION;
358     }
359     if (OpensslEvpDigestVerifyInit(impl->mdCtx, NULL, impl->digestAlg, NULL, pKey) != HCF_OPENSSL_SUCCESS) {
360         HcfPrintOpensslError();
361         LOGD("[error] EVP_DigestVerifyInit failed.");
362         OpensslEvpPkeyFree(pKey);
363         return HCF_ERR_CRYPTO_OPERATION;
364     }
365     OpensslEvpPkeyFree(pKey);
366     impl->status = INITIALIZED;
367     return HCF_SUCCESS;
368 }
369 
EngineVerifyUpdate(HcfVerifySpi * self,HcfBlob * data)370 static HcfResult EngineVerifyUpdate(HcfVerifySpi *self, HcfBlob *data)
371 {
372     if ((self == NULL) || (!HcfIsBlobValid(data))) {
373         LOGE("Invalid input parameter.");
374         return HCF_INVALID_PARAMS;
375     }
376     if (!HcfIsClassMatch((HcfObjectBase *)self, self->base.getClass())) {
377         LOGE("Class not match.");
378         return HCF_INVALID_PARAMS;
379     }
380 
381     HcfVerifySpiSm2OpensslImpl *impl = (HcfVerifySpiSm2OpensslImpl *)self;
382     if (impl->status == UNINITIALIZED) {
383         LOGE("Verify object has not been initialized.");
384         return HCF_INVALID_PARAMS;
385     }
386     if (OpensslEvpDigestVerifyUpdate(impl->mdCtx, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
387         HcfPrintOpensslError();
388         LOGD("[error] EVP_DigestVerifyUpdate failed.");
389         return HCF_ERR_CRYPTO_OPERATION;
390     }
391     impl->status = READY;
392     return HCF_SUCCESS;
393 }
394 
EngineVerifyDoFinal(HcfVerifySpi * self,HcfBlob * data,HcfBlob * signatureData)395 static bool EngineVerifyDoFinal(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureData)
396 {
397     if ((self == NULL) || (!HcfIsBlobValid(signatureData))) {
398         LOGE("Invalid input parameter.");
399         return false;
400     }
401     if (!HcfIsClassMatch((HcfObjectBase *)self, self->base.getClass())) {
402         LOGE("Class not match.");
403         return false;
404     }
405 
406     HcfVerifySpiSm2OpensslImpl *impl = (HcfVerifySpiSm2OpensslImpl *)self;
407     if (HcfIsBlobValid(data)) {
408         if (OpensslEvpDigestVerifyUpdate(impl->mdCtx, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
409             HcfPrintOpensslError();
410             LOGD("[error] EVP_DigestVerifyUpdate failed.");
411             return false;
412         }
413         impl->status = READY;
414     }
415     if (impl->status != READY) {
416         LOGE("The message has not been transferred.");
417         return false;
418     }
419     if (OpensslEvpDigestVerifyFinal(impl->mdCtx, signatureData->data, signatureData->len) != HCF_OPENSSL_SUCCESS) {
420         HcfPrintOpensslError();
421         LOGD("[error] EVP_DigestVerifyFinal failed.");
422         return false;
423     }
424     return true;
425 }
426 
EngineGetSignSpecString(HcfSignSpi * self,SignSpecItem item,char ** returnString)427 static HcfResult EngineGetSignSpecString(HcfSignSpi *self, SignSpecItem item, char **returnString)
428 {
429     (void)self;
430     (void)item;
431     (void)returnString;
432     return HCF_NOT_SUPPORT;
433 }
434 
EngineSetSignSpecUint8Array(HcfSignSpi * self,SignSpecItem item,HcfBlob userId)435 static HcfResult EngineSetSignSpecUint8Array(HcfSignSpi *self, SignSpecItem item, HcfBlob userId)
436 {
437     if (self == NULL) {
438         LOGE("Invalid input parameter");
439         return HCF_INVALID_PARAMS;
440     }
441     if (!HcfIsClassMatch((HcfObjectBase *)self, OPENSSL_SM2_SIGN_CLASS)) {
442         LOGE("Class not match.");
443         return HCF_INVALID_PARAMS;
444     }
445     if (item != SM2_USER_ID_UINT8ARR) {
446         LOGE("Invalid input spec");
447         return HCF_INVALID_PARAMS;
448     }
449     HcfSignSpiSm2OpensslImpl *impl = (HcfSignSpiSm2OpensslImpl *)self;
450     // if it has userId from previous set, it should be free at first;
451     if (impl->userId.data != NULL) {
452         HcfFree(impl->userId.data);
453         impl->userId.data = NULL;
454     }
455     // If userId is NULL or len is 0, the userId will be cleared.
456     if (userId.data == NULL || userId.len == 0) {
457         impl->userId.data = NULL;
458         impl->userId.len = 0;
459     } else {
460         // deep copy two userId, one for impl struct and one for openssl.
461         impl->userId.data = (uint8_t *)HcfMalloc(userId.len, 0);
462         if (impl->userId.data == NULL) {
463             LOGE("Failed to allocate userId data memory");
464             return HCF_ERR_MALLOC;
465         }
466         if (memcpy_s(impl->userId.data, userId.len, userId.data, userId.len) != EOK) {
467             LOGE("memcpy userId failed.");
468             HcfFree(impl->userId.data);
469             impl->userId.data = NULL;
470             return HCF_ERR_MALLOC;
471         }
472         impl->userId.len = userId.len;
473     }
474     // if uninitliszed, userId should only be stored in the struct.
475     // if initliszed, userId should have another copy and set the copy to the evp ctx.
476     if (impl->status == INITIALIZED) {
477         HcfResult ret = SetUserIdFromBlob(impl->userId, impl->mdCtx);
478         if (ret != HCF_SUCCESS) {
479             LOGE("Set userId fail");
480             HcfFree(impl->userId.data);
481             impl->userId.data = NULL;
482             return ret;
483         }
484     }
485     return HCF_SUCCESS;
486 }
487 
EngineGetSignSpecInt(HcfSignSpi * self,SignSpecItem item,int32_t * returnInt)488 static HcfResult EngineGetSignSpecInt(HcfSignSpi *self, SignSpecItem item, int32_t *returnInt)
489 {
490     (void)self;
491     (void)item;
492     (void)returnInt;
493     return HCF_NOT_SUPPORT;
494 }
495 
EngineSetSignSpecInt(HcfSignSpi * self,SignSpecItem item,int32_t saltLen)496 static HcfResult EngineSetSignSpecInt(HcfSignSpi *self, SignSpecItem item, int32_t saltLen)
497 {
498     (void)self;
499     (void)item;
500     (void)saltLen;
501     return HCF_NOT_SUPPORT;
502 }
503 
EngineGetVerifySpecString(HcfVerifySpi * self,SignSpecItem item,char ** returnString)504 static HcfResult EngineGetVerifySpecString(HcfVerifySpi *self, SignSpecItem item, char **returnString)
505 {
506     (void)self;
507     (void)item;
508     (void)returnString;
509     return HCF_NOT_SUPPORT;
510 }
511 
EngineSetVerifySpecUint8Array(HcfVerifySpi * self,SignSpecItem item,HcfBlob userId)512 static HcfResult EngineSetVerifySpecUint8Array(HcfVerifySpi *self, SignSpecItem item, HcfBlob userId)
513 {
514     if (self == NULL) {
515         LOGE("Invalid input parameter");
516         return HCF_INVALID_PARAMS;
517     }
518     if (!HcfIsClassMatch((HcfObjectBase *)self, OPENSSL_SM2_VERIFY_CLASS)) {
519         LOGE("Class not match.");
520         return HCF_INVALID_PARAMS;
521     }
522     if (item != SM2_USER_ID_UINT8ARR) {
523         LOGE("Invalid input spec");
524         return HCF_INVALID_PARAMS;
525     }
526     HcfVerifySpiSm2OpensslImpl *impl = (HcfVerifySpiSm2OpensslImpl *)self;
527     // if it has userId from previous set, it should be free at first;
528     if (impl->userId.data != NULL) {
529         HcfFree(impl->userId.data);
530         impl->userId.data = NULL;
531     }
532     // If userId is NULL or len is 0, the userId will be cleared.
533     if (userId.data == NULL || userId.len == 0) {
534         impl->userId.data = NULL;
535         impl->userId.len = 0;
536     } else {
537         // deep copy two userId, one for impl struct and one for openssl.
538         impl->userId.data = (uint8_t *)HcfMalloc(userId.len, 0);
539         if (impl->userId.data == NULL) {
540             LOGE("Failed to allocate userId data memory");
541             return HCF_ERR_MALLOC;
542         }
543         if (memcpy_s(impl->userId.data, userId.len, userId.data, userId.len) != EOK) {
544             LOGE("memcpy userId failed.");
545             HcfFree(impl->userId.data);
546             impl->userId.data = NULL;
547             return HCF_ERR_MALLOC;
548         }
549         impl->userId.len = userId.len;
550     }
551     // if uninitliszed, userId should only be stored in the struct.
552     // if initliszed, userId should have another copy and set the copy to the evp ctx.
553     if (impl->status == INITIALIZED) {
554         HcfResult ret = SetUserIdFromBlob(impl->userId, impl->mdCtx);
555         if (ret != HCF_SUCCESS) {
556             LOGE("Set userId fail");
557             HcfFree(impl->userId.data);
558             impl->userId.data = NULL;
559             return ret;
560         }
561     }
562     return HCF_SUCCESS;
563 }
564 
EngineGetVerifySpecInt(HcfVerifySpi * self,SignSpecItem item,int32_t * returnInt)565 static HcfResult EngineGetVerifySpecInt(HcfVerifySpi *self, SignSpecItem item, int32_t *returnInt)
566 {
567     (void)self;
568     (void)item;
569     (void)returnInt;
570     return HCF_NOT_SUPPORT;
571 }
572 
EngineSetVerifySpecInt(HcfVerifySpi * self,SignSpecItem item,int32_t saltLen)573 static HcfResult EngineSetVerifySpecInt(HcfVerifySpi *self, SignSpecItem item, int32_t saltLen)
574 {
575     (void)self;
576     (void)item;
577     (void)saltLen;
578     return HCF_NOT_SUPPORT;
579 }
580 
CheckSignInputParamsAndDigest(HcfSignatureParams * params,HcfSignSpi ** returnObj)581 static HcfResult CheckSignInputParamsAndDigest(HcfSignatureParams *params, HcfSignSpi **returnObj)
582 {
583     if ((params == NULL) || (returnObj == NULL)) {
584         LOGE("Invalid input parameter.");
585         return HCF_INVALID_PARAMS;
586     }
587     if (!IsDigestAlgValid(params->md)) {
588         LOGE("Invalid input md parameter.");
589         return HCF_INVALID_PARAMS;
590     }
591     return HCF_SUCCESS;
592 }
593 
CheckVerifyInputParamsAndDigest(HcfSignatureParams * params,HcfVerifySpi ** returnObj)594 static HcfResult CheckVerifyInputParamsAndDigest(HcfSignatureParams *params, HcfVerifySpi **returnObj)
595 {
596     if ((params == NULL) || (returnObj == NULL)) {
597         LOGE("Invalid input parameter.");
598         return HCF_INVALID_PARAMS;
599     }
600     if (!IsDigestAlgValid(params->md)) {
601         LOGE("Invalid input md parameter.");
602         return HCF_INVALID_PARAMS;
603     }
604     return HCF_SUCCESS;
605 }
606 
HcfSignSpiSm2Create(HcfSignatureParams * params,HcfSignSpi ** returnObj)607 HcfResult HcfSignSpiSm2Create(HcfSignatureParams *params, HcfSignSpi **returnObj)
608 {
609     if (CheckSignInputParamsAndDigest(params, returnObj) != HCF_SUCCESS) {
610         LOGE("Check input params and digest failed.");
611         return HCF_INVALID_PARAMS;
612     }
613     EVP_MD *opensslAlg = NULL;
614     int32_t ret = GetOpensslDigestAlg(params->md, &opensslAlg);
615     if (ret != HCF_SUCCESS || opensslAlg == NULL) {
616         LOGE("Failed to Invalid digest!");
617         return HCF_INVALID_PARAMS;
618     }
619 
620     HcfSignSpiSm2OpensslImpl *returnImpl = (HcfSignSpiSm2OpensslImpl *)HcfMalloc(
621         sizeof(HcfSignSpiSm2OpensslImpl), 0);
622     if (returnImpl == NULL) {
623         LOGE("Failed to allocate returnImpl memroy!");
624         return HCF_ERR_MALLOC;
625     }
626     returnImpl->base.base.getClass = GetSm2SignClass;
627     returnImpl->base.base.destroy = DestroySm2Sign;
628     returnImpl->base.engineInit = EngineSignInit;
629     returnImpl->base.engineUpdate = EngineSignUpdate;
630     returnImpl->base.engineSign = EngineSignDoFinal;
631     returnImpl->base.engineGetSignSpecString = EngineGetSignSpecString;
632     returnImpl->base.engineSetSignSpecUint8Array = EngineSetSignSpecUint8Array;
633     returnImpl->base.engineGetSignSpecInt = EngineGetSignSpecInt;
634     returnImpl->base.engineSetSignSpecInt = EngineSetSignSpecInt;
635     returnImpl->digestAlg = opensslAlg;
636     returnImpl->status = UNINITIALIZED;
637     returnImpl->userId.data = (uint8_t *)HcfMalloc(strlen(SM2_DEFAULT_USERID) + 1, 0);
638     if (returnImpl->userId.data == NULL) {
639         LOGE("Failed to allocate userId data memory");
640         HcfFree(returnImpl);
641         returnImpl = NULL;
642         return HCF_ERR_MALLOC;
643     }
644     (void)memcpy_s(returnImpl->userId.data, strlen(SM2_DEFAULT_USERID), SM2_DEFAULT_USERID, strlen(SM2_DEFAULT_USERID));
645     returnImpl->userId.len = strlen(SM2_DEFAULT_USERID);
646     returnImpl->mdCtx = OpensslEvpMdCtxNew();
647     if (returnImpl->mdCtx == NULL) {
648         LOGE("Failed to allocate mdCtx memory!");
649         HcfFree(returnImpl->userId.data);
650         returnImpl->userId.data = NULL;
651         HcfFree(returnImpl);
652         returnImpl = NULL;
653         return HCF_ERR_MALLOC;
654     }
655 
656     *returnObj = (HcfSignSpi *)returnImpl;
657     return HCF_SUCCESS;
658 }
659 
HcfVerifySpiSm2Create(HcfSignatureParams * params,HcfVerifySpi ** returnObj)660 HcfResult HcfVerifySpiSm2Create(HcfSignatureParams *params, HcfVerifySpi **returnObj)
661 {
662     if (CheckVerifyInputParamsAndDigest(params, returnObj) != HCF_SUCCESS) {
663         LOGE("Check input params and digest failed.");
664         return HCF_INVALID_PARAMS;
665     }
666     EVP_MD *opensslAlg = NULL;
667     int32_t ret = GetOpensslDigestAlg(params->md, &opensslAlg);
668     if (ret != HCF_SUCCESS || opensslAlg == NULL) {
669         LOGE("Failed to Invalid digest!");
670         return HCF_INVALID_PARAMS;
671     }
672 
673     HcfVerifySpiSm2OpensslImpl *returnImpl = (HcfVerifySpiSm2OpensslImpl *)HcfMalloc(
674         sizeof(HcfVerifySpiSm2OpensslImpl), 0);
675     if (returnImpl == NULL) {
676         LOGE("Failed to allocate returnImpl memroy!");
677         return HCF_ERR_MALLOC;
678     }
679     returnImpl->base.base.getClass = GetSm2VerifyClass;
680     returnImpl->base.base.destroy = DestroySm2Verify;
681     returnImpl->base.engineInit = EngineVerifyInit;
682     returnImpl->base.engineUpdate = EngineVerifyUpdate;
683     returnImpl->base.engineVerify = EngineVerifyDoFinal;
684     returnImpl->base.engineGetVerifySpecString = EngineGetVerifySpecString;
685     returnImpl->base.engineSetVerifySpecUint8Array = EngineSetVerifySpecUint8Array;
686     returnImpl->base.engineGetVerifySpecInt = EngineGetVerifySpecInt;
687     returnImpl->base.engineSetVerifySpecInt = EngineSetVerifySpecInt;
688     returnImpl->digestAlg = opensslAlg;
689     returnImpl->status = UNINITIALIZED;
690     returnImpl->userId.data = (uint8_t *)HcfMalloc(strlen(SM2_DEFAULT_USERID) + 1, 0);
691     if (returnImpl->userId.data == NULL) {
692         LOGE("Failed to allocate userId data memory");
693         HcfFree(returnImpl);
694         returnImpl = NULL;
695         return HCF_ERR_MALLOC;
696     }
697     (void)memcpy_s(returnImpl->userId.data, strlen(SM2_DEFAULT_USERID), SM2_DEFAULT_USERID, strlen(SM2_DEFAULT_USERID));
698     returnImpl->userId.len = strlen(SM2_DEFAULT_USERID);
699     returnImpl->mdCtx = OpensslEvpMdCtxNew();
700     if (returnImpl->mdCtx == NULL) {
701         LOGE("Failed to allocate mdCtx memory!");
702         HcfFree(returnImpl->userId.data);
703         returnImpl->userId.data = NULL;
704         HcfFree(returnImpl);
705         returnImpl = NULL;
706         return HCF_ERR_MALLOC;
707     }
708 
709     *returnObj = (HcfVerifySpi *)returnImpl;
710     return HCF_SUCCESS;
711 }
712