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         return HCF_ERR_CRYPTO_OPERATION;
298     }
299 
300     returnSignatureData->data = outData;
301     returnSignatureData->len = (uint32_t)maxLen;
302     return HCF_SUCCESS;
303 }
304 
IsSm2VerifyInitInputValid(HcfVerifySpi * self,HcfPubKey * publicKey)305 static bool IsSm2VerifyInitInputValid(HcfVerifySpi *self, HcfPubKey *publicKey)
306 {
307     if ((self == NULL) || (publicKey == NULL)) {
308         LOGE("Invalid input parameter.");
309         return false;
310     }
311     if ((!HcfIsClassMatch((HcfObjectBase *)self, self->base.getClass())) ||
312         (!HcfIsClassMatch((HcfObjectBase *)publicKey, HCF_OPENSSL_SM2_PUB_KEY_CLASS))) {
313         LOGE("Class not match.");
314         return false;
315     }
316 
317     HcfVerifySpiSm2OpensslImpl *impl = (HcfVerifySpiSm2OpensslImpl *)self;
318     if (impl->status != UNINITIALIZED) {
319         LOGE("Repeated initialization is not allowed.");
320         return false;
321     }
322     return true;
323 }
324 
EngineVerifyInit(HcfVerifySpi * self,HcfParamsSpec * params,HcfPubKey * publicKey)325 static HcfResult EngineVerifyInit(HcfVerifySpi *self, HcfParamsSpec *params, HcfPubKey *publicKey)
326 {
327     (void)params;
328     if (!IsSm2VerifyInitInputValid(self, publicKey)) {
329         return HCF_INVALID_PARAMS;
330     }
331 
332     EC_KEY *ecKey = OpensslEcKeyDup(((HcfOpensslSm2PubKey *)publicKey)->ecKey);
333     if (ecKey == NULL) {
334         HcfPrintOpensslError();
335         LOGD("[error] Dup ecKey failed.");
336         return HCF_ERR_CRYPTO_OPERATION;
337     }
338     EVP_PKEY *pKey = OpensslEvpPkeyNew();
339     if (pKey == NULL) {
340         HcfPrintOpensslError();
341         LOGD("[error] New pKey failed.");
342         OpensslEcKeyFree(ecKey);
343         return HCF_ERR_CRYPTO_OPERATION;
344     }
345     if (OpensslEvpPkeyAssignEcKey(pKey, ecKey) != HCF_OPENSSL_SUCCESS) {
346         HcfPrintOpensslError();
347         LOGD("[error] EVP_PKEY_assign_EC_KEY failed.");
348         OpensslEcKeyFree(ecKey);
349         OpensslEvpPkeyFree(pKey);
350         return HCF_ERR_CRYPTO_OPERATION;
351     }
352     HcfVerifySpiSm2OpensslImpl *impl = (HcfVerifySpiSm2OpensslImpl *)self;
353     if (SetSM2Id(impl->mdCtx, pKey, impl->userId) != HCF_SUCCESS) {
354         LOGD("[error] Set sm2 user id failed.");
355         OpensslEvpPkeyFree(pKey);
356         return HCF_ERR_CRYPTO_OPERATION;
357     }
358     if (OpensslEvpDigestVerifyInit(impl->mdCtx, NULL, impl->digestAlg, NULL, pKey) != HCF_OPENSSL_SUCCESS) {
359         HcfPrintOpensslError();
360         LOGD("[error] EVP_DigestVerifyInit failed.");
361         OpensslEvpPkeyFree(pKey);
362         return HCF_ERR_CRYPTO_OPERATION;
363     }
364     OpensslEvpPkeyFree(pKey);
365     impl->status = INITIALIZED;
366     return HCF_SUCCESS;
367 }
368 
EngineVerifyUpdate(HcfVerifySpi * self,HcfBlob * data)369 static HcfResult EngineVerifyUpdate(HcfVerifySpi *self, HcfBlob *data)
370 {
371     if ((self == NULL) || (!HcfIsBlobValid(data))) {
372         LOGE("Invalid input parameter.");
373         return HCF_INVALID_PARAMS;
374     }
375     if (!HcfIsClassMatch((HcfObjectBase *)self, self->base.getClass())) {
376         LOGE("Class not match.");
377         return HCF_INVALID_PARAMS;
378     }
379 
380     HcfVerifySpiSm2OpensslImpl *impl = (HcfVerifySpiSm2OpensslImpl *)self;
381     if (impl->status == UNINITIALIZED) {
382         LOGE("Verify object has not been initialized.");
383         return HCF_INVALID_PARAMS;
384     }
385     if (OpensslEvpDigestVerifyUpdate(impl->mdCtx, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
386         HcfPrintOpensslError();
387         LOGD("[error] EVP_DigestVerifyUpdate failed.");
388         return HCF_ERR_CRYPTO_OPERATION;
389     }
390     impl->status = READY;
391     return HCF_SUCCESS;
392 }
393 
EngineVerifyDoFinal(HcfVerifySpi * self,HcfBlob * data,HcfBlob * signatureData)394 static bool EngineVerifyDoFinal(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureData)
395 {
396     if ((self == NULL) || (!HcfIsBlobValid(signatureData))) {
397         LOGE("Invalid input parameter.");
398         return false;
399     }
400     if (!HcfIsClassMatch((HcfObjectBase *)self, self->base.getClass())) {
401         LOGE("Class not match.");
402         return false;
403     }
404 
405     HcfVerifySpiSm2OpensslImpl *impl = (HcfVerifySpiSm2OpensslImpl *)self;
406     if (HcfIsBlobValid(data)) {
407         if (OpensslEvpDigestVerifyUpdate(impl->mdCtx, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
408             HcfPrintOpensslError();
409             LOGD("[error] EVP_DigestVerifyUpdate failed.");
410             return false;
411         }
412         impl->status = READY;
413     }
414     if (impl->status != READY) {
415         LOGE("The message has not been transferred.");
416         return false;
417     }
418     if (OpensslEvpDigestVerifyFinal(impl->mdCtx, signatureData->data, signatureData->len) != HCF_OPENSSL_SUCCESS) {
419         HcfPrintOpensslError();
420         LOGD("[error] EVP_DigestVerifyFinal failed.");
421         return false;
422     }
423     return true;
424 }
425 
EngineGetSignSpecString(HcfSignSpi * self,SignSpecItem item,char ** returnString)426 static HcfResult EngineGetSignSpecString(HcfSignSpi *self, SignSpecItem item, char **returnString)
427 {
428     (void)self;
429     (void)item;
430     (void)returnString;
431     return HCF_NOT_SUPPORT;
432 }
433 
EngineSetSignSpecUint8Array(HcfSignSpi * self,SignSpecItem item,HcfBlob userId)434 static HcfResult EngineSetSignSpecUint8Array(HcfSignSpi *self, SignSpecItem item, HcfBlob userId)
435 {
436     if (self == NULL) {
437         LOGE("Invalid input parameter");
438         return HCF_INVALID_PARAMS;
439     }
440     if (!HcfIsClassMatch((HcfObjectBase *)self, OPENSSL_SM2_SIGN_CLASS)) {
441         LOGE("Class not match.");
442         return HCF_INVALID_PARAMS;
443     }
444     if (item != SM2_USER_ID_UINT8ARR) {
445         LOGE("Invalid input spec");
446         return HCF_INVALID_PARAMS;
447     }
448     HcfSignSpiSm2OpensslImpl *impl = (HcfSignSpiSm2OpensslImpl *)self;
449     // if it has userId from previous set, it should be free at first;
450     if (impl->userId.data != NULL) {
451         HcfFree(impl->userId.data);
452         impl->userId.data = NULL;
453     }
454     // If userId is NULL or len is 0, the userId will be cleared.
455     if (userId.data == NULL || userId.len == 0) {
456         impl->userId.data = NULL;
457         impl->userId.len = 0;
458     } else {
459         // deep copy two userId, one for impl struct and one for openssl.
460         impl->userId.data = (uint8_t *)HcfMalloc(userId.len, 0);
461         if (impl->userId.data == NULL) {
462             LOGE("Failed to allocate userId data memory");
463             return HCF_ERR_MALLOC;
464         }
465         if (memcpy_s(impl->userId.data, userId.len, userId.data, userId.len) != EOK) {
466             LOGE("memcpy userId failed.");
467             HcfFree(impl->userId.data);
468             return HCF_ERR_MALLOC;
469         }
470         impl->userId.len = userId.len;
471     }
472     // if uninitliszed, userId should only be stored in the struct.
473     // if initliszed, userId should have another copy and set the copy to the evp ctx.
474     if (impl->status == INITIALIZED) {
475         HcfResult ret = SetUserIdFromBlob(impl->userId, impl->mdCtx);
476         if (ret != HCF_SUCCESS) {
477             LOGE("Set userId fail");
478             HcfFree(impl->userId.data);
479             impl->userId.data = NULL;
480             return ret;
481         }
482     }
483     return HCF_SUCCESS;
484 }
485 
EngineGetSignSpecInt(HcfSignSpi * self,SignSpecItem item,int32_t * returnInt)486 static HcfResult EngineGetSignSpecInt(HcfSignSpi *self, SignSpecItem item, int32_t *returnInt)
487 {
488     (void)self;
489     (void)item;
490     (void)returnInt;
491     return HCF_NOT_SUPPORT;
492 }
493 
EngineSetSignSpecInt(HcfSignSpi * self,SignSpecItem item,int32_t saltLen)494 static HcfResult EngineSetSignSpecInt(HcfSignSpi *self, SignSpecItem item, int32_t saltLen)
495 {
496     (void)self;
497     (void)item;
498     (void)saltLen;
499     return HCF_NOT_SUPPORT;
500 }
501 
EngineGetVerifySpecString(HcfVerifySpi * self,SignSpecItem item,char ** returnString)502 static HcfResult EngineGetVerifySpecString(HcfVerifySpi *self, SignSpecItem item, char **returnString)
503 {
504     (void)self;
505     (void)item;
506     (void)returnString;
507     return HCF_NOT_SUPPORT;
508 }
509 
EngineSetVerifySpecUint8Array(HcfVerifySpi * self,SignSpecItem item,HcfBlob userId)510 static HcfResult EngineSetVerifySpecUint8Array(HcfVerifySpi *self, SignSpecItem item, HcfBlob userId)
511 {
512     if (self == NULL) {
513         LOGE("Invalid input parameter");
514         return HCF_INVALID_PARAMS;
515     }
516     if (!HcfIsClassMatch((HcfObjectBase *)self, OPENSSL_SM2_VERIFY_CLASS)) {
517         LOGE("Class not match.");
518         return HCF_INVALID_PARAMS;
519     }
520     if (item != SM2_USER_ID_UINT8ARR) {
521         LOGE("Invalid input spec");
522         return HCF_INVALID_PARAMS;
523     }
524     HcfVerifySpiSm2OpensslImpl *impl = (HcfVerifySpiSm2OpensslImpl *)self;
525     // if it has userId from previous set, it should be free at first;
526     if (impl->userId.data != NULL) {
527         HcfFree(impl->userId.data);
528         impl->userId.data = NULL;
529     }
530     // If userId is NULL or len is 0, the userId will be cleared.
531     if (userId.data == NULL || userId.len == 0) {
532         impl->userId.data = NULL;
533         impl->userId.len = 0;
534     } else {
535         // deep copy two userId, one for impl struct and one for openssl.
536         impl->userId.data = (uint8_t *)HcfMalloc(userId.len, 0);
537         if (impl->userId.data == NULL) {
538             LOGE("Failed to allocate userId data memory");
539             return HCF_ERR_MALLOC;
540         }
541         if (memcpy_s(impl->userId.data, userId.len, userId.data, userId.len) != EOK) {
542             LOGE("memcpy userId failed.");
543             HcfFree(impl->userId.data);
544             return HCF_ERR_MALLOC;
545         }
546         impl->userId.len = userId.len;
547     }
548     // if uninitliszed, userId should only be stored in the struct.
549     // if initliszed, userId should have another copy and set the copy to the evp ctx.
550     if (impl->status == INITIALIZED) {
551         HcfResult ret = SetUserIdFromBlob(impl->userId, impl->mdCtx);
552         if (ret != HCF_SUCCESS) {
553             LOGE("Set userId fail");
554             HcfFree(impl->userId.data);
555             impl->userId.data = NULL;
556             return ret;
557         }
558     }
559     return HCF_SUCCESS;
560 }
561 
EngineGetVerifySpecInt(HcfVerifySpi * self,SignSpecItem item,int32_t * returnInt)562 static HcfResult EngineGetVerifySpecInt(HcfVerifySpi *self, SignSpecItem item, int32_t *returnInt)
563 {
564     (void)self;
565     (void)item;
566     (void)returnInt;
567     return HCF_NOT_SUPPORT;
568 }
569 
EngineSetVerifySpecInt(HcfVerifySpi * self,SignSpecItem item,int32_t saltLen)570 static HcfResult EngineSetVerifySpecInt(HcfVerifySpi *self, SignSpecItem item, int32_t saltLen)
571 {
572     (void)self;
573     (void)item;
574     (void)saltLen;
575     return HCF_NOT_SUPPORT;
576 }
577 
CheckSignInputParamsAndDigest(HcfSignatureParams * params,HcfSignSpi ** returnObj)578 static HcfResult CheckSignInputParamsAndDigest(HcfSignatureParams *params, HcfSignSpi **returnObj)
579 {
580     if ((params == NULL) || (returnObj == NULL)) {
581         LOGE("Invalid input parameter.");
582         return HCF_INVALID_PARAMS;
583     }
584     if (!IsDigestAlgValid(params->md)) {
585         LOGE("Invalid input md parameter.");
586         return HCF_INVALID_PARAMS;
587     }
588     return HCF_SUCCESS;
589 }
590 
CheckVerifyInputParamsAndDigest(HcfSignatureParams * params,HcfVerifySpi ** returnObj)591 static HcfResult CheckVerifyInputParamsAndDigest(HcfSignatureParams *params, HcfVerifySpi **returnObj)
592 {
593     if ((params == NULL) || (returnObj == NULL)) {
594         LOGE("Invalid input parameter.");
595         return HCF_INVALID_PARAMS;
596     }
597     if (!IsDigestAlgValid(params->md)) {
598         LOGE("Invalid input md parameter.");
599         return HCF_INVALID_PARAMS;
600     }
601     return HCF_SUCCESS;
602 }
603 
HcfSignSpiSm2Create(HcfSignatureParams * params,HcfSignSpi ** returnObj)604 HcfResult HcfSignSpiSm2Create(HcfSignatureParams *params, HcfSignSpi **returnObj)
605 {
606     if (CheckSignInputParamsAndDigest(params, returnObj) != HCF_SUCCESS) {
607         LOGE("Check input params and digest failed.");
608         return HCF_INVALID_PARAMS;
609     }
610     EVP_MD *opensslAlg = NULL;
611     int32_t ret = GetOpensslDigestAlg(params->md, &opensslAlg);
612     if (ret != HCF_SUCCESS || opensslAlg == NULL) {
613         LOGE("Failed to Invalid digest!");
614         return HCF_INVALID_PARAMS;
615     }
616 
617     HcfSignSpiSm2OpensslImpl *returnImpl = (HcfSignSpiSm2OpensslImpl *)HcfMalloc(
618         sizeof(HcfSignSpiSm2OpensslImpl), 0);
619     if (returnImpl == NULL) {
620         LOGE("Failed to allocate returnImpl memroy!");
621         return HCF_ERR_MALLOC;
622     }
623     returnImpl->base.base.getClass = GetSm2SignClass;
624     returnImpl->base.base.destroy = DestroySm2Sign;
625     returnImpl->base.engineInit = EngineSignInit;
626     returnImpl->base.engineUpdate = EngineSignUpdate;
627     returnImpl->base.engineSign = EngineSignDoFinal;
628     returnImpl->base.engineGetSignSpecString = EngineGetSignSpecString;
629     returnImpl->base.engineSetSignSpecUint8Array = EngineSetSignSpecUint8Array;
630     returnImpl->base.engineGetSignSpecInt = EngineGetSignSpecInt;
631     returnImpl->base.engineSetSignSpecInt = EngineSetSignSpecInt;
632     returnImpl->digestAlg = opensslAlg;
633     returnImpl->status = UNINITIALIZED;
634     returnImpl->userId.data = (uint8_t *)HcfMalloc(strlen(SM2_DEFAULT_USERID) + 1, 0);
635     if (returnImpl->userId.data == NULL) {
636         LOGE("Failed to allocate userId data memory");
637         HcfFree(returnImpl);
638         return HCF_ERR_MALLOC;
639     }
640     (void)memcpy_s(returnImpl->userId.data, strlen(SM2_DEFAULT_USERID), SM2_DEFAULT_USERID, strlen(SM2_DEFAULT_USERID));
641     returnImpl->userId.len = strlen(SM2_DEFAULT_USERID);
642     returnImpl->mdCtx = OpensslEvpMdCtxNew();
643     if (returnImpl->mdCtx == NULL) {
644         LOGE("Failed to allocate mdCtx memory!");
645         HcfFree(returnImpl->userId.data);
646         HcfFree(returnImpl);
647         return HCF_ERR_MALLOC;
648     }
649 
650     *returnObj = (HcfSignSpi *)returnImpl;
651     return HCF_SUCCESS;
652 }
653 
HcfVerifySpiSm2Create(HcfSignatureParams * params,HcfVerifySpi ** returnObj)654 HcfResult HcfVerifySpiSm2Create(HcfSignatureParams *params, HcfVerifySpi **returnObj)
655 {
656     if (CheckVerifyInputParamsAndDigest(params, returnObj) != HCF_SUCCESS) {
657         LOGE("Check input params and digest failed.");
658         return HCF_INVALID_PARAMS;
659     }
660     EVP_MD *opensslAlg = NULL;
661     int32_t ret = GetOpensslDigestAlg(params->md, &opensslAlg);
662     if (ret != HCF_SUCCESS || opensslAlg == NULL) {
663         LOGE("Failed to Invalid digest!");
664         return HCF_INVALID_PARAMS;
665     }
666 
667     HcfVerifySpiSm2OpensslImpl *returnImpl = (HcfVerifySpiSm2OpensslImpl *)HcfMalloc(
668         sizeof(HcfVerifySpiSm2OpensslImpl), 0);
669     if (returnImpl == NULL) {
670         LOGE("Failed to allocate returnImpl memroy!");
671         return HCF_ERR_MALLOC;
672     }
673     returnImpl->base.base.getClass = GetSm2VerifyClass;
674     returnImpl->base.base.destroy = DestroySm2Verify;
675     returnImpl->base.engineInit = EngineVerifyInit;
676     returnImpl->base.engineUpdate = EngineVerifyUpdate;
677     returnImpl->base.engineVerify = EngineVerifyDoFinal;
678     returnImpl->base.engineGetVerifySpecString = EngineGetVerifySpecString;
679     returnImpl->base.engineSetVerifySpecUint8Array = EngineSetVerifySpecUint8Array;
680     returnImpl->base.engineGetVerifySpecInt = EngineGetVerifySpecInt;
681     returnImpl->base.engineSetVerifySpecInt = EngineSetVerifySpecInt;
682     returnImpl->digestAlg = opensslAlg;
683     returnImpl->status = UNINITIALIZED;
684     returnImpl->userId.data = (uint8_t *)HcfMalloc(strlen(SM2_DEFAULT_USERID) + 1, 0);
685     if (returnImpl->userId.data == NULL) {
686         LOGE("Failed to allocate userId data memory");
687         HcfFree(returnImpl);
688         return HCF_ERR_MALLOC;
689     }
690     (void)memcpy_s(returnImpl->userId.data, strlen(SM2_DEFAULT_USERID), SM2_DEFAULT_USERID, strlen(SM2_DEFAULT_USERID));
691     returnImpl->userId.len = strlen(SM2_DEFAULT_USERID);
692     returnImpl->mdCtx = OpensslEvpMdCtxNew();
693     if (returnImpl->mdCtx == NULL) {
694         LOGE("Failed to allocate mdCtx memory!");
695         HcfFree(returnImpl->userId.data);
696         HcfFree(returnImpl);
697         return HCF_ERR_MALLOC;
698     }
699 
700     *returnObj = (HcfVerifySpi *)returnImpl;
701     return HCF_SUCCESS;
702 }
703