1 /*
2 * Copyright (C) 2022-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 "cipher_rsa_openssl.h"
17 #include "securec.h"
18 #include "openssl/rsa.h"
19 #include "rsa_openssl_common.h"
20 #include "log.h"
21 #include "memory.h"
22 #include "openssl_adapter.h"
23 #include "openssl_class.h"
24 #include "openssl_common.h"
25 #include "stdbool.h"
26 #include "string.h"
27 #include "utils.h"
28
29 static const char *EngineGetClass(void);
30
31 typedef struct {
32 HcfCipherGeneratorSpi super;
33
34 CipherAttr attr;
35
36 CryptoStatus initFlag;
37
38 EVP_PKEY_CTX *ctx;
39
40 HcfBlob pSource;
41 } HcfCipherRsaGeneratorSpiImpl;
42
CheckCipherInitParams(enum HcfCryptoMode opMode,HcfKey * key)43 static HcfResult CheckCipherInitParams(enum HcfCryptoMode opMode, HcfKey *key)
44 {
45 switch (opMode) {
46 case ENCRYPT_MODE:
47 if (!IsClassMatch((HcfObjectBase *)key, OPENSSL_RSA_PUBKEY_CLASS)) {
48 LOGE("Class not match");
49 return HCF_INVALID_PARAMS;
50 }
51 break;
52 case DECRYPT_MODE:
53 if (!IsClassMatch((HcfObjectBase *)key, OPENSSL_RSA_PRIKEY_CLASS)) {
54 LOGE("Class not match");
55 return HCF_INVALID_PARAMS;
56 }
57 break;
58 default:
59 LOGE("Invalid opMode %u", opMode);
60 return HCF_INVALID_PARAMS;
61 }
62
63 return HCF_SUCCESS;
64 }
65
DuplicateRsaFromKey(HcfKey * key,enum HcfCryptoMode opMode,RSA ** dupRsa)66 static HcfResult DuplicateRsaFromKey(HcfKey *key, enum HcfCryptoMode opMode, RSA **dupRsa)
67 {
68 HcfResult ret = HCF_SUCCESS;
69 if (opMode == ENCRYPT_MODE) {
70 ret = DuplicateRsa(((HcfOpensslRsaPubKey *)key)->pk, false, dupRsa);
71 if (ret != HCF_SUCCESS) {
72 LOGD("[error] dup pub RSA fail.");
73 return ret;
74 }
75 LOGD("dup pub RSA success.");
76 } else if (opMode == DECRYPT_MODE) {
77 // dup will check if rsa is NULL
78 ret = DuplicateRsa(((HcfOpensslRsaPriKey *)key)->sk, true, dupRsa);
79 if (ret != HCF_SUCCESS) {
80 LOGD("[error] dup pri RSA fail.");
81 return ret;
82 }
83 LOGD("dup pri RSA success.");
84 } else {
85 LOGD("[error] OpMode not match.");
86 return HCF_INVALID_PARAMS;
87 }
88 return ret;
89 }
90
InitEvpPkeyCtx(HcfCipherRsaGeneratorSpiImpl * impl,HcfKey * key,enum HcfCryptoMode opMode)91 static HcfResult InitEvpPkeyCtx(HcfCipherRsaGeneratorSpiImpl *impl, HcfKey *key, enum HcfCryptoMode opMode)
92 {
93 RSA *rsa = NULL;
94 HcfResult ret = HCF_SUCCESS;
95 ret = DuplicateRsaFromKey(key, opMode, &rsa);
96 if (ret != HCF_SUCCESS) {
97 LOGD("[error] DuplicateRsaFromKey fail.");
98 return ret;
99 }
100 EVP_PKEY *pkey = NewEvpPkeyByRsa(rsa, false);
101 if (pkey == NULL) {
102 LOGD("[error] NewEvpPkeyByRsa fail");
103 HcfPrintOpensslError();
104 Openssl_RSA_free(rsa);
105 return HCF_ERR_CRYPTO_OPERATION;
106 }
107 impl->ctx = EVP_PKEY_CTX_new(pkey, NULL);
108 if (impl->ctx == NULL) {
109 LOGD("[error] EVP_PKEY_CTX_new fail");
110 HcfPrintOpensslError();
111 Openssl_EVP_PKEY_free(pkey);
112 return HCF_ERR_CRYPTO_OPERATION;
113 }
114 int32_t sslRet = HCF_OPENSSL_SUCCESS;
115 if (opMode == ENCRYPT_MODE) {
116 sslRet = Openssl_EVP_PKEY_encrypt_init(impl->ctx);
117 } else {
118 sslRet = Openssl_EVP_PKEY_decrypt_init(impl->ctx);
119 }
120 if (sslRet != HCF_OPENSSL_SUCCESS) {
121 LOGD("[error] Init EVP_PKEY fail");
122 HcfPrintOpensslError();
123 Openssl_EVP_PKEY_free(pkey);
124 Openssl_EVP_PKEY_CTX_free(impl->ctx);
125 return HCF_ERR_CRYPTO_OPERATION;
126 }
127 Openssl_EVP_PKEY_free(pkey);
128 return HCF_SUCCESS;
129 }
130
SetPsourceFromBlob(HcfBlob pSource,EVP_PKEY_CTX * ctx)131 static HcfResult SetPsourceFromBlob(HcfBlob pSource, EVP_PKEY_CTX *ctx)
132 {
133 // If pSource is NULL or len is 0, the pSource will be cleared.
134 if (pSource.data == NULL || pSource.len == 0) {
135 if (Openssl_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, NULL, 0) != HCF_OPENSSL_SUCCESS) {
136 LOGD("[error] Openssl Set psource fail");
137 HcfPrintOpensslError();
138 return HCF_ERR_CRYPTO_OPERATION;
139 }
140 }
141 // deep copy from pSource
142 uint8_t *opensslPsource = (uint8_t *)HcfMalloc(pSource.len, 0);
143 if (opensslPsource == NULL) {
144 LOGE("Failed to allocate openssl pSource data memory");
145 return HCF_ERR_MALLOC;
146 }
147 (void)memcpy_s(opensslPsource, pSource.len, pSource.data, pSource.len);
148
149 if (Openssl_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, opensslPsource, pSource.len) != HCF_OPENSSL_SUCCESS) {
150 LOGD("[error] Openssl Set psource fail");
151 HcfPrintOpensslError();
152 HcfFree(opensslPsource);
153 return HCF_ERR_CRYPTO_OPERATION;
154 }
155 return HCF_SUCCESS;
156 }
157
158 // all parmas have been checked in CheckRsaCipherParams, this function does not need check.
SetDetailParams(HcfCipherRsaGeneratorSpiImpl * impl)159 static HcfResult SetDetailParams(HcfCipherRsaGeneratorSpiImpl *impl)
160 {
161 CipherAttr attr = impl->attr;
162 int32_t opensslPadding = 0;
163 (void)GetOpensslPadding(attr.paddingMode, &opensslPadding);
164 if (Openssl_EVP_PKEY_CTX_set_rsa_padding(impl->ctx, opensslPadding) != HCF_OPENSSL_SUCCESS) {
165 LOGD("[error] Cipher set padding fail.");
166 HcfPrintOpensslError();
167 return HCF_ERR_CRYPTO_OPERATION;
168 }
169 if (attr.paddingMode != HCF_OPENSSL_RSA_PKCS1_OAEP_PADDING) {
170 return HCF_SUCCESS;
171 }
172 // pkcs oaep
173 EVP_MD *md = NULL;
174 EVP_MD *mgf1md = NULL;
175 (void)GetOpensslDigestAlg(attr.md, &md);
176 (void)GetOpensslDigestAlg(attr.mgf1md, &mgf1md);
177 // set md and mgf1md
178 if (Openssl_EVP_PKEY_CTX_set_rsa_oaep_md(impl->ctx, md) != HCF_OPENSSL_SUCCESS
179 || Openssl_EVP_PKEY_CTX_set_rsa_mgf1_md(impl->ctx, mgf1md) != HCF_OPENSSL_SUCCESS) {
180 LOGD("[error] Set md or mgf1md fail");
181 HcfPrintOpensslError();
182 return HCF_ERR_CRYPTO_OPERATION;
183 }
184 // default EVP pSource is NULL, need not set.
185 if (impl->pSource.data != NULL && impl->pSource.len > 0) {
186 HcfResult ret = SetPsourceFromBlob(impl->pSource, impl->ctx);
187 if (ret != HCF_SUCCESS) {
188 // check if clean the pSource when init fail at it.
189 HcfFree(impl->pSource.data);
190 impl->pSource.data = NULL;
191 LOGD("[error] Set pSource fail, clean the pSource");
192 return ret;
193 }
194 }
195 return HCF_SUCCESS;
196 }
197
198 // The EVP_PKEY_CTX_set0_rsa_oaep_label() macro sets the RSA OAEP label to label and its length to len.
199 // https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_CTX_set0_rsa_oaep_label.html
SetRsaCipherSpecUint8Array(HcfCipherGeneratorSpi * self,CipherSpecItem item,HcfBlob pSource)200 static HcfResult SetRsaCipherSpecUint8Array(HcfCipherGeneratorSpi *self, CipherSpecItem item, HcfBlob pSource)
201 {
202 // If pSource is NULL or len is 0, the pSource will be cleared.
203 if (self == NULL) {
204 LOGE("Param is invalid.");
205 return HCF_INVALID_PARAMS;
206 }
207 if (item != OAEP_MGF1_PSRC_UINT8ARR) {
208 LOGE("Invalid cipher spec item");
209 return HCF_INVALID_PARAMS;
210 }
211 if (!IsClassMatch((HcfObjectBase *)self, EngineGetClass())) {
212 LOGE("Class not match");
213 return HCF_INVALID_PARAMS;
214 }
215 HcfCipherRsaGeneratorSpiImpl *impl = (HcfCipherRsaGeneratorSpiImpl *)self;
216 CipherAttr attr = impl->attr;
217 if (attr.paddingMode != HCF_OPENSSL_RSA_PKCS1_OAEP_PADDING) {
218 LOGE("Psource is not supported.");
219 return HCF_INVALID_PARAMS;
220 }
221 // if it has pSource from previous set, it should be free at first;
222 if (impl->pSource.data != NULL) {
223 HcfFree(impl->pSource.data);
224 impl->pSource.data = NULL;
225 }
226 // If pSource is NULL or len is 0, the pSource will be cleared.
227 if (pSource.data == NULL || pSource.len == 0) {
228 impl->pSource.data = NULL;
229 impl->pSource.len = 0;
230 } else {
231 // deep copy two pSource, one for impl struct and one for openssl.
232 impl->pSource.data = (uint8_t *)HcfMalloc(pSource.len, 0);
233 if (impl->pSource.data == NULL) {
234 LOGE("Failed to allocate pSource data memory");
235 return HCF_ERR_MALLOC;
236 }
237 (void)memcpy_s(impl->pSource.data, pSource.len, pSource.data, pSource.len);
238 impl->pSource.len = pSource.len;
239 }
240 // if uninitliszed, pSource should only be stored in the struct.
241 // if initliszed, pSource should have another copy and set the copy to the evp ctx.
242 if (impl->initFlag == INITIALIZED) {
243 HcfResult ret = SetPsourceFromBlob(impl->pSource, impl->ctx);
244 if (ret != HCF_SUCCESS) {
245 LOGE("Set pSource fail");
246 HcfFree(impl->pSource.data);
247 impl->pSource.data = NULL;
248 return ret;
249 }
250 }
251 return HCF_SUCCESS;
252 }
253
GetRsaCipherSpecUint8Array(HcfCipherGeneratorSpi * self,CipherSpecItem item,HcfBlob * returnPSource)254 static HcfResult GetRsaCipherSpecUint8Array(HcfCipherGeneratorSpi *self, CipherSpecItem item, HcfBlob* returnPSource)
255 {
256 if (self == NULL || returnPSource == NULL) {
257 LOGE("Param is invalid.");
258 return HCF_INVALID_PARAMS;
259 }
260 if (item != OAEP_MGF1_PSRC_UINT8ARR) {
261 LOGE("Invalid cipher spec item");
262 return HCF_INVALID_PARAMS;
263 }
264 if (!IsClassMatch((HcfObjectBase *)self, EngineGetClass())) {
265 LOGE("Class not match");
266 return HCF_INVALID_PARAMS;
267 }
268 HcfCipherRsaGeneratorSpiImpl *impl = (HcfCipherRsaGeneratorSpiImpl *)self;
269 CipherAttr attr = impl->attr;
270 if (attr.paddingMode != HCF_OPENSSL_RSA_PKCS1_OAEP_PADDING) {
271 LOGE("Psource is not supported.");
272 return HCF_INVALID_PARAMS;
273 }
274 // use the pSource from struct at first.
275 if (impl->pSource.data != NULL && impl->pSource.len > 0) {
276 uint8_t *pSource = (uint8_t *)HcfMalloc(impl->pSource.len, 0);
277 if (pSource == NULL) {
278 LOGE("Failed to allocate pSource memory!");
279 return HCF_ERR_MALLOC;
280 }
281 (void)memcpy_s(pSource, impl->pSource.len, impl->pSource.data, impl->pSource.len);
282 returnPSource->data = pSource;
283 returnPSource->len = impl->pSource.len;
284 return HCF_SUCCESS;
285 }
286 // without pSource in the struct, use the default get func of openssl after init.
287 // default situation, the pSource is NULL and len is 0, return fail.
288 return HCF_INVALID_PARAMS;
289 }
290
GetRsaCipherSpecString(HcfCipherGeneratorSpi * self,CipherSpecItem item,char ** returnString)291 static HcfResult GetRsaCipherSpecString(HcfCipherGeneratorSpi *self, CipherSpecItem item, char **returnString)
292 {
293 if (self == NULL || returnString == NULL) {
294 LOGE("Param is invalid.");
295 return HCF_INVALID_PARAMS;
296 }
297 if (!IsClassMatch((HcfObjectBase *)self, EngineGetClass())) {
298 LOGE("Class not match");
299 return HCF_INVALID_PARAMS;
300 }
301 HcfCipherRsaGeneratorSpiImpl *impl = (HcfCipherRsaGeneratorSpiImpl *)self;
302 CipherAttr attr = impl->attr;
303 if (attr.paddingMode != HCF_OPENSSL_RSA_PKCS1_OAEP_PADDING) {
304 LOGE("cipher spec string is not supported.");
305 return HCF_INVALID_PARAMS;
306 }
307 HcfResult ret = HCF_INVALID_PARAMS;
308 switch (item) {
309 case OAEP_MD_NAME_STR:
310 ret = GetRsaSpecStringMd((const HcfAlgParaValue)(attr.md), returnString);
311 break;
312 case OAEP_MGF_NAME_STR:
313 // only support mgf1
314 ret = GetRsaSpecStringMGF(returnString);
315 break;
316 case OAEP_MGF1_MD_STR:
317 ret = GetRsaSpecStringMd((const HcfAlgParaValue)(attr.mgf1md), returnString);
318 break;
319 default:
320 LOGE("Invalid input cipher spec");
321 return HCF_INVALID_PARAMS;
322 }
323 return ret;
324 }
325
EngineInit(HcfCipherGeneratorSpi * self,enum HcfCryptoMode opMode,HcfKey * key,HcfParamsSpec * params)326 static HcfResult EngineInit(HcfCipherGeneratorSpi *self, enum HcfCryptoMode opMode,
327 HcfKey *key, HcfParamsSpec *params)
328 {
329 (void)params;
330 if (self == NULL || key == NULL) {
331 LOGE("Param is invalid.");
332 return HCF_INVALID_PARAMS;
333 }
334 if (!IsClassMatch((HcfObjectBase *)self, EngineGetClass())) {
335 LOGE("Class not match");
336 return HCF_INVALID_PARAMS;
337 }
338 HcfCipherRsaGeneratorSpiImpl *impl = (HcfCipherRsaGeneratorSpiImpl *)self;
339 if (impl->initFlag != UNINITIALIZED) {
340 LOGE("The cipher has been initialize, don't init again.");
341 return HCF_INVALID_PARAMS;
342 }
343
344 // check opMode is matched with Key
345 if (CheckCipherInitParams(opMode, key) != HCF_SUCCESS) {
346 LOGE("OpMode dismatch with keyType.");
347 return HCF_INVALID_PARAMS;
348 }
349 impl->attr.mode = (int32_t)opMode;
350 if (InitEvpPkeyCtx(impl, key, opMode) != HCF_SUCCESS) {
351 LOGD("[error] InitEvpPkeyCtx fail");
352 return HCF_ERR_CRYPTO_OPERATION;
353 }
354
355 if (SetDetailParams(impl) != HCF_SUCCESS) {
356 Openssl_EVP_PKEY_CTX_free(impl->ctx);
357 impl->ctx = NULL;
358 LOGD("[error] SetDetailParams fail.");
359 return HCF_ERR_CRYPTO_OPERATION;
360 }
361 impl->initFlag = INITIALIZED;
362 return HCF_SUCCESS;
363 }
364
EngineUpdate(HcfCipherGeneratorSpi * self,HcfBlob * input,HcfBlob * output)365 static HcfResult EngineUpdate(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfBlob *output)
366 {
367 LOGE("Openssl don't support update");
368 (void)self;
369 (void)input;
370 (void)output;
371 return HCF_NOT_SUPPORT;
372 }
373
DoRsaCrypt(EVP_PKEY_CTX * ctx,HcfBlob * input,HcfBlob * output,int32_t mode)374 static HcfResult DoRsaCrypt(EVP_PKEY_CTX *ctx, HcfBlob *input, HcfBlob *output, int32_t mode)
375 {
376 int32_t ret = HCF_OPENSSL_SUCCESS;
377 if (mode == ENCRYPT_MODE) {
378 ret = Openssl_EVP_PKEY_encrypt(ctx, output->data, &output->len, input->data, input->len);
379 } else if (mode == DECRYPT_MODE) {
380 ret = Openssl_EVP_PKEY_decrypt(ctx, output->data, &output->len, input->data, input->len);
381 } else {
382 LOGE("OpMode is invalid.");
383 return HCF_INVALID_PARAMS;
384 }
385 if (ret != HCF_OPENSSL_SUCCESS) {
386 LOGD("[error] RSA openssl error");
387 HcfPrintOpensslError();
388 return HCF_ERR_CRYPTO_OPERATION;
389 }
390 return HCF_SUCCESS;
391 }
392
EngineDoFinal(HcfCipherGeneratorSpi * self,HcfBlob * input,HcfBlob * output)393 static HcfResult EngineDoFinal(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfBlob *output)
394 {
395 if (self == NULL || !IsBlobValid(input) || output == NULL) {
396 LOGE("Param is invalid.");
397 return HCF_INVALID_PARAMS;
398 }
399 if (!IsClassMatch((HcfObjectBase *)self, EngineGetClass())) {
400 LOGE("Class not match");
401 return HCF_INVALID_PARAMS;
402 }
403 HcfCipherRsaGeneratorSpiImpl *impl = (HcfCipherRsaGeneratorSpiImpl *)self;
404 if (impl->initFlag != INITIALIZED) {
405 LOGE("RSACipher has not been init");
406 return HCF_INVALID_PARAMS;
407 }
408 CipherAttr attr = impl->attr;
409 output->len = 0;
410 output->data = NULL;
411 HcfResult ret = DoRsaCrypt(impl->ctx, input, output, attr.mode);
412 if (ret != HCF_SUCCESS) {
413 LOGD("[error] GetOutLen fail.");
414 return HCF_ERR_CRYPTO_OPERATION;
415 }
416 LOGD("ouput data len is %zu.", output->len);
417
418 output->data = (uint8_t *)HcfMalloc(sizeof(uint8_t) * output->len, 0);
419 ret = DoRsaCrypt(impl->ctx, input, output, attr.mode);
420 if (ret != HCF_SUCCESS) {
421 HcfFree(output->data);
422 output->data = NULL;
423 output->len = 0;
424 return HCF_ERR_CRYPTO_OPERATION;
425 }
426 return HCF_SUCCESS;
427 }
428
EngineDestroySpiImpl(HcfObjectBase * generator)429 static void EngineDestroySpiImpl(HcfObjectBase *generator)
430 {
431 if (generator == NULL) {
432 return;
433 }
434 if (!IsClassMatch((HcfObjectBase *)generator, EngineGetClass())) {
435 LOGE("Class not match");
436 return;
437 }
438 HcfCipherRsaGeneratorSpiImpl *impl = (HcfCipherRsaGeneratorSpiImpl *)generator;
439 Openssl_EVP_PKEY_CTX_free(impl->ctx);
440 impl->ctx = NULL;
441 HcfFree(impl->pSource.data);
442 impl->pSource.data = NULL;
443 HcfFree(impl);
444 impl = NULL;
445 }
446
EngineGetClass(void)447 static const char *EngineGetClass(void)
448 {
449 return OPENSSL_RSA_CIPHER_CLASS;
450 }
451
CheckRsaCipherParams(CipherAttr * params)452 static HcfResult CheckRsaCipherParams(CipherAttr *params)
453 {
454 int32_t opensslPadding = 0;
455 if (params->algo != HCF_ALG_RSA) {
456 LOGE("Cipher algo %u is invalid.", params->algo);
457 return HCF_INVALID_PARAMS;
458 }
459 if (GetOpensslPadding(params->paddingMode, &opensslPadding) != HCF_SUCCESS) {
460 LOGE("Cipher create without padding mode");
461 return HCF_INVALID_PARAMS;
462 }
463 // cannot use pss padding mode in RSA cipher.
464 if (opensslPadding == RSA_PKCS1_PSS_PADDING) {
465 LOGE("Cipher cannot use PSS mode");
466 return HCF_INVALID_PARAMS;
467 }
468 if (params->paddingMode == HCF_OPENSSL_RSA_PKCS1_OAEP_PADDING) {
469 EVP_MD *md = NULL;
470 EVP_MD *mgf1md = NULL;
471 (void)GetOpensslDigestAlg(params->md, &md);
472 (void)GetOpensslDigestAlg(params->mgf1md, &mgf1md);
473 if (md == NULL) {
474 LOGE("Use pkcs1_oaep padding, but md is NULL");
475 return HCF_INVALID_PARAMS;
476 }
477 if (mgf1md == NULL) {
478 LOGE("Use pkcs1_oaep padding, but mgf1md is NULL");
479 return HCF_INVALID_PARAMS;
480 }
481 }
482 return HCF_SUCCESS;
483 }
484
HcfCipherRsaCipherSpiCreate(CipherAttr * params,HcfCipherGeneratorSpi ** generator)485 HcfResult HcfCipherRsaCipherSpiCreate(CipherAttr *params, HcfCipherGeneratorSpi **generator)
486 {
487 if (generator == NULL || params == NULL) {
488 LOGE("Invalid input parameter.");
489 return HCF_INVALID_PARAMS;
490 }
491 HcfCipherRsaGeneratorSpiImpl *returnImpl = (HcfCipherRsaGeneratorSpiImpl *)HcfMalloc(
492 sizeof(HcfCipherRsaGeneratorSpiImpl), 0);
493 if (returnImpl == NULL) {
494 LOGE("Malloc rsa cipher fail.");
495 return HCF_ERR_MALLOC;
496 }
497 (void)memcpy_s(&returnImpl->attr, sizeof(CipherAttr), params, sizeof(CipherAttr));
498
499 if (CheckRsaCipherParams(&returnImpl->attr) != HCF_SUCCESS) {
500 HcfFree(returnImpl);
501 returnImpl = NULL;
502 return HCF_INVALID_PARAMS;
503 }
504
505 returnImpl->super.init = EngineInit;
506 returnImpl->super.update = EngineUpdate;
507 returnImpl->super.doFinal = EngineDoFinal;
508 returnImpl->super.setCipherSpecUint8Array = SetRsaCipherSpecUint8Array;
509 returnImpl->super.getCipherSpecString = GetRsaCipherSpecString;
510 returnImpl->super.getCipherSpecUint8Array = GetRsaCipherSpecUint8Array;
511 returnImpl->super.base.destroy = EngineDestroySpiImpl;
512 returnImpl->super.base.getClass = EngineGetClass;
513 returnImpl->initFlag = UNINITIALIZED;
514 *generator = (HcfCipherGeneratorSpi *)returnImpl;
515 LOGD("Rsa Cipher create success.");
516 return HCF_SUCCESS;
517 }
518