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