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