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