1 /*
2 * Copyright (C) 2022 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 "ecdsa_openssl.h"
17
18 #include <openssl/bio.h>
19 #include <openssl/err.h>
20
21 #include "algorithm_parameter.h"
22 #include "openssl_adapter.h"
23 #include "openssl_class.h"
24 #include "openssl_common.h"
25 #include "log.h"
26 #include "memory.h"
27 #include "utils.h"
28
29 #define OPENSSL_ECC_SIGN_CLASS "OPENSSL.ECC.SIGN"
30 #define OPENSSL_ECC_VERIFY_CLASS "OPENSSL.ECC.VERIFY"
31
32 typedef struct {
33 HcfSignSpi base;
34
35 const EVP_MD *digestAlg;
36
37 EVP_MD_CTX *ctx;
38
39 CryptoStatus status;
40 } HcfSignSpiEcdsaOpensslImpl;
41
42 typedef struct {
43 HcfVerifySpi base;
44
45 const EVP_MD *digestAlg;
46
47 EVP_MD_CTX *ctx;
48
49 CryptoStatus status;
50 } HcfVerifySpiEcdsaOpensslImpl;
51
IsDigestAlgValid(uint32_t alg)52 static bool IsDigestAlgValid(uint32_t alg)
53 {
54 if ((alg == HCF_OPENSSL_DIGEST_SHA1) || (alg == HCF_OPENSSL_DIGEST_SHA224) ||
55 (alg == HCF_OPENSSL_DIGEST_SHA256) ||(alg == HCF_OPENSSL_DIGEST_SHA384) ||
56 (alg == HCF_OPENSSL_DIGEST_SHA512)) {
57 return true;
58 } else {
59 LOGE("Invalid digest num is %u.", alg);
60 return false;
61 }
62 }
63
IsBrainPoolDigestAlgValid(uint32_t alg)64 static bool IsBrainPoolDigestAlgValid(uint32_t alg)
65 {
66 if ((alg == HCF_OPENSSL_DIGEST_SHA1) || (alg == HCF_OPENSSL_DIGEST_SHA224) ||
67 (alg == HCF_OPENSSL_DIGEST_SHA256) || (alg == HCF_OPENSSL_DIGEST_SHA384) ||
68 (alg == HCF_OPENSSL_DIGEST_SHA512) || (alg == HCF_OPENSSL_DIGEST_MD5)) {
69 return true;
70 } else {
71 LOGE("Invalid digest num is %u.", alg);
72 return false;
73 }
74 }
75
76 // export interfaces
GetEcdsaSignClass(void)77 static const char *GetEcdsaSignClass(void)
78 {
79 return OPENSSL_ECC_SIGN_CLASS;
80 }
81
GetEcdsaVerifyClass(void)82 static const char *GetEcdsaVerifyClass(void)
83 {
84 return OPENSSL_ECC_VERIFY_CLASS;
85 }
86
DestroyEcdsaSign(HcfObjectBase * self)87 static void DestroyEcdsaSign(HcfObjectBase *self)
88 {
89 if (self == NULL) {
90 LOGE("Class is null.");
91 return;
92 }
93 if (!IsClassMatch(self, GetEcdsaSignClass())) {
94 LOGE("Class not match.");
95 return;
96 }
97 HcfSignSpiEcdsaOpensslImpl *impl = (HcfSignSpiEcdsaOpensslImpl *)self;
98 Openssl_EVP_MD_CTX_free(impl->ctx);
99 impl->ctx = NULL;
100 HcfFree(impl);
101 }
102
DestroyEcdsaVerify(HcfObjectBase * self)103 static void DestroyEcdsaVerify(HcfObjectBase *self)
104 {
105 if (self == NULL) {
106 LOGE("Class is null.");
107 return;
108 }
109 if (!IsClassMatch(self, GetEcdsaVerifyClass())) {
110 LOGE("Class not match.");
111 return;
112 }
113 HcfVerifySpiEcdsaOpensslImpl *impl = (HcfVerifySpiEcdsaOpensslImpl *)self;
114 Openssl_EVP_MD_CTX_free(impl->ctx);
115 impl->ctx = NULL;
116 HcfFree(impl);
117 }
118
EngineSignInit(HcfSignSpi * self,HcfParamsSpec * params,HcfPriKey * privateKey)119 static HcfResult EngineSignInit(HcfSignSpi *self, HcfParamsSpec *params, HcfPriKey *privateKey)
120 {
121 (void)params;
122 if ((self == NULL) || (privateKey == NULL)) {
123 LOGE("Invalid input parameter.");
124 return HCF_INVALID_PARAMS;
125 }
126 if ((!IsClassMatch((HcfObjectBase *)self, GetEcdsaSignClass())) ||
127 (!IsClassMatch((HcfObjectBase *)privateKey, HCF_OPENSSL_ECC_PRI_KEY_CLASS))) {
128 LOGE("Class not match.");
129 return HCF_INVALID_PARAMS;
130 }
131
132 HcfSignSpiEcdsaOpensslImpl *impl = (HcfSignSpiEcdsaOpensslImpl *)self;
133 if (impl->status != UNINITIALIZED) {
134 LOGE("Repeated initialization is not allowed.");
135 return HCF_INVALID_PARAMS;
136 }
137 // dup will check if ecKey is NULL
138 EC_KEY *ecKey = Openssl_EC_KEY_dup(((HcfOpensslEccPriKey *)privateKey)->ecKey);
139 if (ecKey == NULL) {
140 HcfPrintOpensslError();
141 LOGD("[error] Dup ecKey failed.");
142 return HCF_ERR_CRYPTO_OPERATION;
143 }
144 EVP_PKEY *pKey = Openssl_EVP_PKEY_new();
145 if (pKey == NULL) {
146 HcfPrintOpensslError();
147 LOGD("[error] Dup pKey failed.");
148 Openssl_EC_KEY_free(ecKey);
149 return HCF_ERR_CRYPTO_OPERATION;
150 }
151 if (Openssl_EVP_PKEY_assign_EC_KEY(pKey, ecKey) != HCF_OPENSSL_SUCCESS) {
152 HcfPrintOpensslError();
153 LOGD("[error] EVP_PKEY_assign_EC_KEY failed.");
154 Openssl_EC_KEY_free(ecKey);
155 Openssl_EVP_PKEY_free(pKey);
156 return HCF_ERR_CRYPTO_OPERATION;
157 }
158 if (Openssl_EVP_DigestSignInit(impl->ctx, NULL, impl->digestAlg, NULL, pKey) != HCF_OPENSSL_SUCCESS) {
159 HcfPrintOpensslError();
160 LOGD("[error] EVP_DigestSignInit failed.");
161 Openssl_EVP_PKEY_free(pKey);
162 return HCF_ERR_CRYPTO_OPERATION;
163 }
164 Openssl_EVP_PKEY_free(pKey);
165 impl->status = INITIALIZED;
166 return HCF_SUCCESS;
167 }
168
EngineSignUpdate(HcfSignSpi * self,HcfBlob * data)169 static HcfResult EngineSignUpdate(HcfSignSpi *self, HcfBlob *data)
170 {
171 if ((self == NULL) || (!IsBlobValid(data))) {
172 LOGE("Invalid input parameter.");
173 return HCF_INVALID_PARAMS;
174 }
175 if (!IsClassMatch((HcfObjectBase *)self, GetEcdsaSignClass())) {
176 LOGE("Class not match.");
177 return HCF_INVALID_PARAMS;
178 }
179 HcfSignSpiEcdsaOpensslImpl *impl = (HcfSignSpiEcdsaOpensslImpl *)self;
180 if (impl->status == UNINITIALIZED) {
181 LOGE("Sign object has not been initialized.");
182 return HCF_INVALID_PARAMS;
183 }
184 if (Openssl_EVP_DigestSignUpdate(impl->ctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
185 HcfPrintOpensslError();
186 LOGD("[error] EVP_DigestSignUpdate failed.");
187 return HCF_ERR_CRYPTO_OPERATION;
188 }
189 impl->status = READY;
190 return HCF_SUCCESS;
191 }
192
EngineSignDoFinal(HcfSignSpi * self,HcfBlob * data,HcfBlob * returnSignatureData)193 static HcfResult EngineSignDoFinal(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSignatureData)
194 {
195 if ((self == NULL) || (returnSignatureData == NULL)) {
196 LOGE("Invalid input parameter.");
197 return HCF_INVALID_PARAMS;
198 }
199 if (!IsClassMatch((HcfObjectBase *)self, GetEcdsaSignClass())) {
200 LOGE("Class not match.");
201 return HCF_INVALID_PARAMS;
202 }
203
204 HcfSignSpiEcdsaOpensslImpl *impl = (HcfSignSpiEcdsaOpensslImpl *)self;
205 if (IsBlobValid(data)) {
206 if (Openssl_EVP_DigestSignUpdate(impl->ctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
207 HcfPrintOpensslError();
208 LOGD("[error] EVP_DigestSignUpdate failed.");
209 return HCF_ERR_CRYPTO_OPERATION;
210 }
211 impl->status = READY;
212 }
213 if (impl->status != READY) {
214 LOGE("The message has not been transferred.");
215 return HCF_INVALID_PARAMS;
216 }
217 size_t maxLen;
218 if (Openssl_EVP_DigestSignFinal(impl->ctx, NULL, &maxLen) != HCF_OPENSSL_SUCCESS) {
219 HcfPrintOpensslError();
220 LOGD("[error] EVP_DigestSignFinal failed.");
221 return HCF_ERR_CRYPTO_OPERATION;
222 }
223 uint8_t *outData = (uint8_t *)HcfMalloc(maxLen, 0);
224 if (outData == NULL) {
225 LOGE("Failed to allocate outData memory!");
226 return HCF_ERR_MALLOC;
227 }
228 size_t actualLen = maxLen;
229 if (Openssl_EVP_DigestSignFinal(impl->ctx, outData, &actualLen) != HCF_OPENSSL_SUCCESS) {
230 HcfPrintOpensslError();
231 LOGD("[error] EVP_DigestSignFinal failed.");
232 HcfFree(outData);
233 return HCF_ERR_CRYPTO_OPERATION;
234 }
235 if (actualLen > maxLen) {
236 LOGD("[error] signature data too long.");
237 HcfFree(outData);
238 return HCF_ERR_CRYPTO_OPERATION;
239 }
240
241 returnSignatureData->data = outData;
242 returnSignatureData->len = (uint32_t)actualLen;
243 return HCF_SUCCESS;
244 }
245
EngineVerifyInit(HcfVerifySpi * self,HcfParamsSpec * params,HcfPubKey * publicKey)246 static HcfResult EngineVerifyInit(HcfVerifySpi *self, HcfParamsSpec *params, HcfPubKey *publicKey)
247 {
248 (void)params;
249 if ((self == NULL) || (publicKey == NULL)) {
250 LOGE("Invalid input parameter.");
251 return HCF_INVALID_PARAMS;
252 }
253 if ((!IsClassMatch((HcfObjectBase *)self, GetEcdsaVerifyClass())) ||
254 (!IsClassMatch((HcfObjectBase *)publicKey, HCF_OPENSSL_ECC_PUB_KEY_CLASS))) {
255 LOGE("Class not match.");
256 return HCF_INVALID_PARAMS;
257 }
258
259 HcfVerifySpiEcdsaOpensslImpl *impl = (HcfVerifySpiEcdsaOpensslImpl *)self;
260 if (impl->status != UNINITIALIZED) {
261 LOGE("Repeated initialization is not allowed.");
262 return HCF_INVALID_PARAMS;
263 }
264 EC_KEY *ecKey = Openssl_EC_KEY_dup(((HcfOpensslEccPubKey *)publicKey)->ecKey);
265 if (ecKey == NULL) {
266 HcfPrintOpensslError();
267 LOGD("[error] Dup ecKey failed.");
268 return HCF_ERR_CRYPTO_OPERATION;
269 }
270 EVP_PKEY *pKey = Openssl_EVP_PKEY_new();
271 if (pKey == NULL) {
272 HcfPrintOpensslError();
273 LOGD("[error] New pKey failed.");
274 Openssl_EC_KEY_free(ecKey);
275 return HCF_ERR_CRYPTO_OPERATION;
276 }
277 if (Openssl_EVP_PKEY_assign_EC_KEY(pKey, ecKey) != HCF_OPENSSL_SUCCESS) {
278 HcfPrintOpensslError();
279 LOGD("[error] EVP_PKEY_assign_EC_KEY failed.");
280 Openssl_EC_KEY_free(ecKey);
281 Openssl_EVP_PKEY_free(pKey);
282 return HCF_ERR_CRYPTO_OPERATION;
283 }
284 if (Openssl_EVP_DigestVerifyInit(impl->ctx, NULL, impl->digestAlg, NULL, pKey) != HCF_OPENSSL_SUCCESS) {
285 HcfPrintOpensslError();
286 LOGD("[error] EVP_DigestVerifyInit failed.");
287 Openssl_EVP_PKEY_free(pKey);
288 return HCF_ERR_CRYPTO_OPERATION;
289 }
290 Openssl_EVP_PKEY_free(pKey);
291 impl->status = INITIALIZED;
292 return HCF_SUCCESS;
293 }
294
EngineVerifyUpdate(HcfVerifySpi * self,HcfBlob * data)295 static HcfResult EngineVerifyUpdate(HcfVerifySpi *self, HcfBlob *data)
296 {
297 if ((self == NULL) || (!IsBlobValid(data))) {
298 LOGE("Invalid input parameter.");
299 return HCF_INVALID_PARAMS;
300 }
301 if (!IsClassMatch((HcfObjectBase *)self, GetEcdsaVerifyClass())) {
302 LOGE("Class not match.");
303 return HCF_INVALID_PARAMS;
304 }
305
306 HcfVerifySpiEcdsaOpensslImpl *impl = (HcfVerifySpiEcdsaOpensslImpl *)self;
307 if (impl->status == UNINITIALIZED) {
308 LOGE("Verify object has not been initialized.");
309 return HCF_INVALID_PARAMS;
310 }
311 if (Openssl_EVP_DigestVerifyUpdate(impl->ctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
312 HcfPrintOpensslError();
313 LOGD("[error] EVP_DigestVerifyUpdate failed.");
314 return HCF_ERR_CRYPTO_OPERATION;
315 }
316 impl->status = READY;
317 return HCF_SUCCESS;
318 }
319
EngineVerifyDoFinal(HcfVerifySpi * self,HcfBlob * data,HcfBlob * signatureData)320 static bool EngineVerifyDoFinal(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureData)
321 {
322 if ((self == NULL) || (!IsBlobValid(signatureData))) {
323 LOGE("Invalid input parameter.");
324 return false;
325 }
326 if (!IsClassMatch((HcfObjectBase *)self, GetEcdsaVerifyClass())) {
327 LOGE("Class not match.");
328 return false;
329 }
330
331 HcfVerifySpiEcdsaOpensslImpl *impl = (HcfVerifySpiEcdsaOpensslImpl *)self;
332 if (IsBlobValid(data)) {
333 if (Openssl_EVP_DigestVerifyUpdate(impl->ctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
334 HcfPrintOpensslError();
335 LOGD("[error] EVP_DigestVerifyUpdate failed.");
336 return false;
337 }
338 impl->status = READY;
339 }
340 if (impl->status != READY) {
341 LOGE("The message has not been transferred.");
342 return false;
343 }
344 if (Openssl_EVP_DigestVerifyFinal(impl->ctx, signatureData->data, signatureData->len) != HCF_OPENSSL_SUCCESS) {
345 HcfPrintOpensslError();
346 LOGD("[error] EVP_DigestVerifyFinal failed.");
347 return false;
348 }
349 return true;
350 }
351
EngineSetSignEcdsaSpecInt(HcfSignSpi * self,SignSpecItem item,int32_t saltLen)352 static HcfResult EngineSetSignEcdsaSpecInt(HcfSignSpi *self, SignSpecItem item, int32_t saltLen)
353 {
354 (void)self;
355 (void)item;
356 (void)saltLen;
357 return HCF_NOT_SUPPORT;
358 }
359
EngineSetVerifyEcdsaSpecInt(HcfVerifySpi * self,SignSpecItem item,int32_t saltLen)360 static HcfResult EngineSetVerifyEcdsaSpecInt(HcfVerifySpi *self, SignSpecItem item, int32_t saltLen)
361 {
362 (void)self;
363 (void)item;
364 (void)saltLen;
365 return HCF_NOT_SUPPORT;
366 }
367
EngineGetSignEcdsaSpecInt(HcfSignSpi * self,SignSpecItem item,int32_t * returnInt)368 static HcfResult EngineGetSignEcdsaSpecInt(HcfSignSpi *self, SignSpecItem item, int32_t *returnInt)
369 {
370 (void)self;
371 (void)item;
372 (void)returnInt;
373 return HCF_NOT_SUPPORT;
374 }
375
EngineGetVerifyEcdsaSpecInt(HcfVerifySpi * self,SignSpecItem item,int32_t * returnInt)376 static HcfResult EngineGetVerifyEcdsaSpecInt(HcfVerifySpi *self, SignSpecItem item, int32_t *returnInt)
377 {
378 (void)self;
379 (void)item;
380 (void)returnInt;
381 return HCF_NOT_SUPPORT;
382 }
383
EngineGetSignEcdsaSpecString(HcfSignSpi * self,SignSpecItem item,char ** returnString)384 static HcfResult EngineGetSignEcdsaSpecString(HcfSignSpi *self, SignSpecItem item, char **returnString)
385 {
386 (void)self;
387 (void)item;
388 (void)returnString;
389 return HCF_NOT_SUPPORT;
390 }
391
EngineSetSignEcdsaSpecUint8Array(HcfSignSpi * self,SignSpecItem item,HcfBlob blob)392 static HcfResult EngineSetSignEcdsaSpecUint8Array(HcfSignSpi *self, SignSpecItem item, HcfBlob blob)
393 {
394 (void)self;
395 (void)item;
396 (void)blob;
397 return HCF_NOT_SUPPORT;
398 }
399
EngineGetVerifyEcdsaSpecString(HcfVerifySpi * self,SignSpecItem item,char ** returnString)400 static HcfResult EngineGetVerifyEcdsaSpecString(HcfVerifySpi *self, SignSpecItem item, char **returnString)
401 {
402 (void)self;
403 (void)item;
404 (void)returnString;
405 return HCF_NOT_SUPPORT;
406 }
407
EngineSetVerifyEcdsaSpecUint8Array(HcfVerifySpi * self,SignSpecItem item,HcfBlob blob)408 static HcfResult EngineSetVerifyEcdsaSpecUint8Array(HcfVerifySpi *self, SignSpecItem item, HcfBlob blob)
409 {
410 (void)self;
411 (void)item;
412 (void)blob;
413 return HCF_NOT_SUPPORT;
414 }
415
HcfSignSpiEcdsaCreate(HcfSignatureParams * params,HcfSignSpi ** returnObj)416 HcfResult HcfSignSpiEcdsaCreate(HcfSignatureParams *params, HcfSignSpi **returnObj)
417 {
418 if ((params == NULL) || (returnObj == NULL)) {
419 LOGE("Invalid input parameter.");
420 return HCF_INVALID_PARAMS;
421 }
422 if (params->algo == HCF_ALG_ECC_BRAINPOOL) {
423 if (!IsBrainPoolDigestAlgValid(params->md)) {
424 LOGE("Invalid md.");
425 return HCF_INVALID_PARAMS;
426 }
427 } else {
428 if (!IsDigestAlgValid(params->md)) {
429 LOGE("Invalid md.");
430 return HCF_INVALID_PARAMS;
431 }
432 }
433 EVP_MD *opensslAlg = NULL;
434 int32_t ret = GetOpensslDigestAlg(params->md, &opensslAlg);
435 if (ret != HCF_SUCCESS || opensslAlg == NULL) {
436 LOGE("Failed to Invalid digest!");
437 return HCF_INVALID_PARAMS;
438 }
439
440 HcfSignSpiEcdsaOpensslImpl *returnImpl = (HcfSignSpiEcdsaOpensslImpl *)HcfMalloc(
441 sizeof(HcfSignSpiEcdsaOpensslImpl), 0);
442 if (returnImpl == NULL) {
443 LOGE("Failed to allocate returnImpl memroy!");
444 return HCF_ERR_MALLOC;
445 }
446 returnImpl->base.base.getClass = GetEcdsaSignClass;
447 returnImpl->base.base.destroy = DestroyEcdsaSign;
448 returnImpl->base.engineInit = EngineSignInit;
449 returnImpl->base.engineUpdate = EngineSignUpdate;
450 returnImpl->base.engineSign = EngineSignDoFinal;
451 returnImpl->base.engineSetSignSpecInt = EngineSetSignEcdsaSpecInt;
452 returnImpl->base.engineGetSignSpecInt = EngineGetSignEcdsaSpecInt;
453 returnImpl->base.engineGetSignSpecString = EngineGetSignEcdsaSpecString;
454 returnImpl->base.engineSetSignSpecUint8Array = EngineSetSignEcdsaSpecUint8Array;
455 returnImpl->digestAlg = opensslAlg;
456 returnImpl->status = UNINITIALIZED;
457 returnImpl->ctx = Openssl_EVP_MD_CTX_new();
458 if (returnImpl->ctx == NULL) {
459 LOGE("Failed to allocate ctx memory!");
460 HcfFree(returnImpl);
461 return HCF_ERR_MALLOC;
462 }
463
464 *returnObj = (HcfSignSpi *)returnImpl;
465 return HCF_SUCCESS;
466 }
467
HcfVerifySpiEcdsaCreate(HcfSignatureParams * params,HcfVerifySpi ** returnObj)468 HcfResult HcfVerifySpiEcdsaCreate(HcfSignatureParams *params, HcfVerifySpi **returnObj)
469 {
470 if ((params == NULL) || (returnObj == NULL)) {
471 LOGE("Invalid input parameter.");
472 return HCF_INVALID_PARAMS;
473 }
474 if (params->algo == HCF_ALG_ECC_BRAINPOOL) {
475 if (!IsBrainPoolDigestAlgValid(params->md)) {
476 LOGE("Invalid md.");
477 return HCF_INVALID_PARAMS;
478 }
479 } else {
480 if (!IsDigestAlgValid(params->md)) {
481 LOGE("Invalid md.");
482 return HCF_INVALID_PARAMS;
483 }
484 }
485 EVP_MD *opensslAlg = NULL;
486 int32_t ret = GetOpensslDigestAlg(params->md, &opensslAlg);
487 if (ret != HCF_SUCCESS || opensslAlg == NULL) {
488 LOGE("Failed to Invalid digest!");
489 return HCF_INVALID_PARAMS;
490 }
491
492 HcfVerifySpiEcdsaOpensslImpl *returnImpl = (HcfVerifySpiEcdsaOpensslImpl *)HcfMalloc(
493 sizeof(HcfVerifySpiEcdsaOpensslImpl), 0);
494 if (returnImpl == NULL) {
495 LOGE("Failed to allocate returnImpl memroy!");
496 return HCF_ERR_MALLOC;
497 }
498 returnImpl->base.base.getClass = GetEcdsaVerifyClass;
499 returnImpl->base.base.destroy = DestroyEcdsaVerify;
500 returnImpl->base.engineInit = EngineVerifyInit;
501 returnImpl->base.engineUpdate = EngineVerifyUpdate;
502 returnImpl->base.engineVerify = EngineVerifyDoFinal;
503 returnImpl->base.engineSetVerifySpecInt = EngineSetVerifyEcdsaSpecInt;
504 returnImpl->base.engineGetVerifySpecInt = EngineGetVerifyEcdsaSpecInt;
505 returnImpl->base.engineGetVerifySpecString = EngineGetVerifyEcdsaSpecString;
506 returnImpl->base.engineSetVerifySpecUint8Array = EngineSetVerifyEcdsaSpecUint8Array;
507 returnImpl->digestAlg = opensslAlg;
508 returnImpl->status = UNINITIALIZED;
509 returnImpl->ctx = Openssl_EVP_MD_CTX_new();
510 if (returnImpl->ctx == NULL) {
511 LOGE("Failed to allocate ctx memory!");
512 HcfFree(returnImpl);
513 return HCF_ERR_MALLOC;
514 }
515
516 *returnObj = (HcfVerifySpi *)returnImpl;
517 return HCF_SUCCESS;
518 }
519