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