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