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 #include "sm4_openssl.h"
16 #include "securec.h"
17 #include "blob.h"
18 #include "log.h"
19 #include "memory.h"
20 #include "result.h"
21 #include "utils.h"
22 #include "aes_openssl_common.h"
23 #include "sym_common_defines.h"
24 #include "openssl_adapter.h"
25 #include "openssl_common.h"
26 #include "openssl_class.h"
27
28 #define MAX_AAD_LEN 2048
29 #define SM4_BLOCK_SIZE 16
30 #define SM4_SIZE_128 16
31 #define GCM_IV_MIN_LEN 1
32 #define GCM_IV_MAX_LEN 128
33 #define GCM_TAG_SIZE 16
34 #define CBC_CTR_OFB_CFB_IV_LEN 16
35
36 typedef struct {
37 HcfCipherGeneratorSpi base;
38 CipherAttr attr;
39 CipherData *cipherData;
40 } HcfCipherSm4GeneratorSpiOpensslImpl;
41
GetSm4GeneratorClass(void)42 static const char *GetSm4GeneratorClass(void)
43 {
44 return OPENSSL_SM4_CIPHER_CLASS;
45 }
46
CipherEcbType(SymKeyImpl * symKey)47 static const EVP_CIPHER *CipherEcbType(SymKeyImpl *symKey)
48 {
49 switch (symKey->keyMaterial.len) {
50 case SM4_SIZE_128:
51 return OpensslEvpSm4Ecb();
52 default:
53 break;
54 }
55 return NULL;
56 }
57
CipherCbcType(SymKeyImpl * symKey)58 static const EVP_CIPHER *CipherCbcType(SymKeyImpl *symKey)
59 {
60 switch (symKey->keyMaterial.len) {
61 case SM4_SIZE_128:
62 return OpensslEvpSm4Cbc();
63 default:
64 break;
65 }
66 return NULL;
67 }
68
CipherCtrType(SymKeyImpl * symKey)69 static const EVP_CIPHER *CipherCtrType(SymKeyImpl *symKey)
70 {
71 switch (symKey->keyMaterial.len) {
72 case SM4_SIZE_128:
73 return OpensslEvpSm4Ctr();
74 default:
75 break;
76 }
77 return NULL;
78 }
79
CipherOfbType(SymKeyImpl * symKey)80 static const EVP_CIPHER *CipherOfbType(SymKeyImpl *symKey)
81 {
82 switch (symKey->keyMaterial.len) {
83 case SM4_SIZE_128:
84 return OpensslEvpSm4Ofb();
85 default:
86 break;
87 }
88 return NULL;
89 }
90
CipherCfbType(SymKeyImpl * symKey)91 static const EVP_CIPHER *CipherCfbType(SymKeyImpl *symKey)
92 {
93 switch (symKey->keyMaterial.len) {
94 case SM4_SIZE_128:
95 return OpensslEvpSm4Cfb();
96 default:
97 break;
98 }
99 return NULL;
100 }
101
CipherCfb128Type(SymKeyImpl * symKey)102 static const EVP_CIPHER *CipherCfb128Type(SymKeyImpl *symKey)
103 {
104 switch (symKey->keyMaterial.len) {
105 case SM4_SIZE_128:
106 return OpensslEvpSm4Cfb128();
107 default:
108 break;
109 }
110 return NULL;
111 }
112
CipherGcmType(SymKeyImpl * symKey)113 static const EVP_CIPHER *CipherGcmType(SymKeyImpl *symKey)
114 {
115 (void)symKey;
116 return (const EVP_CIPHER *)OpensslEvpCipherFetch(NULL, "SM4-GCM", NULL);
117 }
118
DefaultCipherType(SymKeyImpl * symKey)119 static const EVP_CIPHER *DefaultCipherType(SymKeyImpl *symKey)
120 {
121 return CipherEcbType(symKey);
122 }
123
GetCipherType(HcfCipherSm4GeneratorSpiOpensslImpl * impl,SymKeyImpl * symKey)124 static const EVP_CIPHER *GetCipherType(HcfCipherSm4GeneratorSpiOpensslImpl *impl, SymKeyImpl *symKey)
125 {
126 switch (impl->attr.mode) {
127 case HCF_ALG_MODE_ECB:
128 return CipherEcbType(symKey);
129 case HCF_ALG_MODE_CBC:
130 return CipherCbcType(symKey);
131 case HCF_ALG_MODE_CTR:
132 return CipherCtrType(symKey);
133 case HCF_ALG_MODE_OFB:
134 return CipherOfbType(symKey);
135 case HCF_ALG_MODE_CFB:
136 return CipherCfbType(symKey);
137 case HCF_ALG_MODE_CFB128:
138 return CipherCfb128Type(symKey);
139 case HCF_ALG_MODE_GCM:
140 return CipherGcmType(symKey);
141 default:
142 break;
143 }
144 return DefaultCipherType(symKey);
145 }
146
IsIvParamsValid(HcfIvParamsSpec * params)147 static HcfResult IsIvParamsValid(HcfIvParamsSpec *params)
148 {
149 if (params == NULL) {
150 LOGE("params is null!");
151 return HCF_INVALID_PARAMS;
152 }
153 if ((params->iv.data == NULL) || (params->iv.len != CBC_CTR_OFB_CFB_IV_LEN)) {
154 LOGE("iv is invalid!");
155 return HCF_INVALID_PARAMS;
156 }
157 return HCF_SUCCESS;
158 }
159
IsGcmParamsValid(HcfGcmParamsSpec * params)160 static bool IsGcmParamsValid(HcfGcmParamsSpec *params)
161 {
162 if (params == NULL) {
163 LOGE("params is null!");
164 return false;
165 }
166 if ((params->iv.data == NULL) || (params->iv.len < GCM_IV_MIN_LEN) || (params->iv.len > GCM_IV_MAX_LEN)) {
167 LOGE("iv is invalid!");
168 return false;
169 }
170 if ((params->tag.data == NULL) || (params->tag.len == 0)) {
171 LOGE("tag is invalid!");
172 return false;
173 }
174 return true;
175 }
176
InitAadAndTagFromGcmParams(enum HcfCryptoMode opMode,HcfGcmParamsSpec * params,CipherData * data)177 static HcfResult InitAadAndTagFromGcmParams(enum HcfCryptoMode opMode, HcfGcmParamsSpec *params, CipherData *data)
178 {
179 if (!IsGcmParamsValid(params)) {
180 LOGE("gcm params is invalid!");
181 return HCF_INVALID_PARAMS;
182 }
183
184 if (params->aad.data != NULL && params->aad.len != 0) {
185 data->aad = (uint8_t *)HcfMalloc(params->aad.len, 0);
186 if (data->aad == NULL) {
187 LOGE("aad malloc failed!");
188 return HCF_ERR_MALLOC;
189 }
190 (void)memcpy_s(data->aad, params->aad.len, params->aad.data, params->aad.len);
191 data->aadLen = params->aad.len;
192 data->aead = true;
193 } else {
194 data->aad = NULL;
195 data->aadLen = 0;
196 data->aead = false;
197 }
198 data->tagLen = params->tag.len;
199 if (opMode == ENCRYPT_MODE) {
200 return HCF_SUCCESS;
201 }
202 data->tag = (uint8_t *)HcfMalloc(params->tag.len, 0);
203 if (data->tag == NULL) {
204 HcfFree(data->aad);
205 data->aad = NULL;
206 LOGE("tag malloc failed!");
207 return HCF_ERR_MALLOC;
208 }
209 (void)memcpy_s(data->tag, params->tag.len, params->tag.data, params->tag.len);
210 return HCF_SUCCESS;
211 }
212
InitCipherData(HcfCipherGeneratorSpi * self,enum HcfCryptoMode opMode,HcfParamsSpec * params,CipherData ** cipherData)213 static HcfResult InitCipherData(HcfCipherGeneratorSpi* self, enum HcfCryptoMode opMode,
214 HcfParamsSpec* params, CipherData **cipherData)
215 {
216 HcfResult ret = HCF_ERR_MALLOC;
217 *cipherData = (CipherData *)HcfMalloc(sizeof(CipherData), 0);
218 if (*cipherData == NULL) {
219 LOGE("malloc is failed!");
220 return ret;
221 }
222 HcfCipherSm4GeneratorSpiOpensslImpl *cipherImpl = (HcfCipherSm4GeneratorSpiOpensslImpl *)self;
223 HcfAlgParaValue mode = cipherImpl->attr.mode;
224
225 (*cipherData)->enc = opMode;
226 (*cipherData)->ctx = OpensslEvpCipherCtxNew();
227 if ((*cipherData)->ctx == NULL) {
228 HcfPrintOpensslError();
229 LOGE("Failed to allocate ctx memory!");
230 goto clearup;
231 }
232
233 ret = HCF_SUCCESS;
234 switch (mode) {
235 case HCF_ALG_MODE_CBC:
236 case HCF_ALG_MODE_CTR:
237 case HCF_ALG_MODE_OFB:
238 case HCF_ALG_MODE_CFB:
239 case HCF_ALG_MODE_CFB128:
240 (void)IsIvParamsValid((HcfIvParamsSpec *)params);
241 break;
242 case HCF_ALG_MODE_GCM:
243 ret = InitAadAndTagFromGcmParams(opMode, (HcfGcmParamsSpec *)params, *cipherData);
244 break;
245 case HCF_ALG_MODE_CCM:
246 ret = HCF_NOT_SUPPORT;
247 break;
248 default:
249 break;
250 }
251 if (ret != HCF_SUCCESS) {
252 LOGE("init cipher data failed!");
253 goto clearup;
254 }
255 return ret;
256 clearup:
257 FreeCipherData(cipherData);
258 return ret;
259 }
260
GetPaddingMode(HcfCipherSm4GeneratorSpiOpensslImpl * cipherImpl)261 static HcfResult GetPaddingMode(HcfCipherSm4GeneratorSpiOpensslImpl* cipherImpl)
262 {
263 switch (cipherImpl->attr.paddingMode) {
264 case HCF_ALG_NOPADDING:
265 break;
266 case HCF_ALG_PADDING_PKCS5:
267 return EVP_PADDING_PKCS7;
268 case HCF_ALG_PADDING_PKCS7:
269 return EVP_PADDING_PKCS7;
270 default:
271 LOGE("No Params!");
272 break;
273 }
274 return HCF_SUCCESS;
275 }
276
CheckParam(HcfCipherGeneratorSpi * self,enum HcfCryptoMode opMode,HcfKey * key)277 static HcfResult CheckParam(HcfCipherGeneratorSpi* self, enum HcfCryptoMode opMode, HcfKey* key)
278 {
279 if ((self == NULL) || (key == NULL)) {
280 LOGE("Invalid input parameter.");
281 return HCF_INVALID_PARAMS;
282 }
283 if (!HcfIsClassMatch((HcfObjectBase *)self, self->base.getClass())) {
284 LOGE("Class is not match.");
285 return HCF_INVALID_PARAMS;
286 }
287 if (!HcfIsClassMatch((HcfObjectBase *)key, OPENSSL_SYM_KEY_CLASS)) {
288 LOGE("Class is not match.");
289 return HCF_INVALID_PARAMS;
290 }
291 if (opMode != ENCRYPT_MODE && opMode != DECRYPT_MODE) {
292 LOGE("Invalid opMode %d", opMode);
293 return HCF_INVALID_PARAMS;
294 }
295 SymKeyImpl* keyImpl = (SymKeyImpl*)key;
296 if (keyImpl->keyMaterial.len < SM4_SIZE_128) {
297 LOGE("Init failed, the input key size is smaller than keySize specified in cipher.");
298 return HCF_INVALID_PARAMS;
299 }
300 HcfCipherSm4GeneratorSpiOpensslImpl *cipherImpl = (HcfCipherSm4GeneratorSpiOpensslImpl *)self;
301 if (cipherImpl->attr.mode == HCF_ALG_MODE_GCM) {
302 cipherImpl->attr.paddingMode = HCF_ALG_NOPADDING;
303 LOGD("Default paddingMode is %u", HCF_ALG_NOPADDING);
304 }
305 if (cipherImpl->attr.paddingMode != HCF_ALG_NOPADDING && cipherImpl->attr.paddingMode != HCF_ALG_PADDING_PKCS5 &&
306 cipherImpl->attr.paddingMode != HCF_ALG_PADDING_PKCS7) {
307 LOGE("Invalid padding mode %u", cipherImpl->attr.paddingMode);
308 return HCF_INVALID_PARAMS;
309 }
310 return HCF_SUCCESS;
311 }
312
SetCipherAttribute(HcfCipherSm4GeneratorSpiOpensslImpl * cipherImpl,SymKeyImpl * keyImpl,int enc,HcfParamsSpec * params)313 static bool SetCipherAttribute(HcfCipherSm4GeneratorSpiOpensslImpl *cipherImpl, SymKeyImpl *keyImpl,
314 int enc, HcfParamsSpec *params)
315 {
316 CipherData *data = cipherImpl->cipherData;
317 HcfAlgParaValue mode = cipherImpl->attr.mode;
318 const EVP_CIPHER *cipher = GetCipherType(cipherImpl, keyImpl);
319 if (cipher == NULL) {
320 HcfPrintOpensslError();
321 LOGE("fetch cipher failed!");
322 return false;
323 }
324 if (mode != HCF_ALG_MODE_GCM) {
325 if (OpensslEvpCipherInit(data->ctx, cipher, keyImpl->keyMaterial.data,
326 GetIv(params), enc) != HCF_OPENSSL_SUCCESS) {
327 HcfPrintOpensslError();
328 LOGE("EVP_CipherInit failed!");
329 return false;
330 }
331 return true;
332 }
333 if (OpensslEvpCipherInit(data->ctx, cipher, NULL, NULL, enc) != HCF_OPENSSL_SUCCESS) {
334 HcfPrintOpensslError();
335 LOGE("EVP_CipherInit failed!");
336 OpensslEvpCipherFree((EVP_CIPHER *)cipher);
337 return false;
338 }
339 OpensslEvpCipherFree((EVP_CIPHER *)cipher);
340 if (OpensslEvpCipherCtxCtrl(data->ctx, EVP_CTRL_AEAD_SET_IVLEN,
341 GetIvLen(params), NULL) != HCF_OPENSSL_SUCCESS) {
342 HcfPrintOpensslError();
343 LOGE("EVP_Cipher set iv len failed!");
344 return false;
345 }
346 if (OpensslEvpCipherInit(data->ctx, NULL, keyImpl->keyMaterial.data,
347 GetIv(params), enc) != HCF_OPENSSL_SUCCESS) {
348 HcfPrintOpensslError();
349 LOGE("EVP_CipherInit failed!");
350 return false;
351 }
352 return true;
353 }
354
EngineCipherInit(HcfCipherGeneratorSpi * self,enum HcfCryptoMode opMode,HcfKey * key,HcfParamsSpec * params)355 static HcfResult EngineCipherInit(HcfCipherGeneratorSpi* self, enum HcfCryptoMode opMode,
356 HcfKey* key, HcfParamsSpec* params)
357 {
358 if (CheckParam(self, opMode, key) != HCF_SUCCESS) {
359 return HCF_INVALID_PARAMS;
360 }
361 HcfCipherSm4GeneratorSpiOpensslImpl *cipherImpl = (HcfCipherSm4GeneratorSpiOpensslImpl *)self;
362 SymKeyImpl* keyImpl = (SymKeyImpl*)key;
363 int32_t enc = (opMode == ENCRYPT_MODE) ? 1 : 0;
364 cipherImpl->attr.keySize = keyImpl->keyMaterial.len;
365 HcfResult res = InitCipherData(self, opMode, params, &(cipherImpl->cipherData));
366 if (res != HCF_SUCCESS) {
367 LOGE("InitCipherData failed");
368 return res;
369 }
370 CipherData *data = cipherImpl->cipherData;
371 HcfResult ret = HCF_ERR_CRYPTO_OPERATION;
372 if (!SetCipherAttribute(cipherImpl, keyImpl, enc, params)) {
373 LOGE("Set cipher attribute failed!");
374 goto clearup;
375 }
376 if (OpensslEvpCipherCtxSetPadding(data->ctx, GetPaddingMode(cipherImpl)) != HCF_OPENSSL_SUCCESS) {
377 HcfPrintOpensslError();
378 LOGE("Set padding failed.");
379 goto clearup;
380 }
381 return HCF_SUCCESS;
382 clearup:
383 FreeCipherData(&(cipherImpl->cipherData));
384 return ret;
385 }
386
AllocateOutput(HcfBlob * input,HcfBlob * output,bool * isUpdateInput)387 static HcfResult AllocateOutput(HcfBlob* input, HcfBlob* output, bool *isUpdateInput)
388 {
389 uint32_t outLen = SM4_BLOCK_SIZE + SM4_BLOCK_SIZE;
390 if (HcfIsBlobValid(input)) {
391 outLen += input->len;
392 *isUpdateInput = true;
393 }
394 output->data = (uint8_t*)HcfMalloc(outLen, 0);
395 if (output->data == NULL) {
396 LOGE("Malloc output failed.");
397 return HCF_ERR_MALLOC;
398 }
399 output->len = outLen;
400 return HCF_SUCCESS;
401 }
402
CommonUpdate(CipherData * data,HcfBlob * input,HcfBlob * output)403 static HcfResult CommonUpdate(CipherData *data, HcfBlob *input, HcfBlob *output)
404 {
405 int32_t ret = OpensslEvpCipherUpdate(data->ctx, output->data, (int *)&output->len,
406 input->data, input->len);
407 if (ret != HCF_OPENSSL_SUCCESS) {
408 HcfPrintOpensslError();
409 LOGE("cipher update failed!");
410 return HCF_ERR_CRYPTO_OPERATION;
411 }
412 return HCF_SUCCESS;
413 }
414
AeadUpdate(CipherData * data,HcfAlgParaValue mode,HcfBlob * input,HcfBlob * output)415 static HcfResult AeadUpdate(CipherData *data, HcfAlgParaValue mode, HcfBlob *input, HcfBlob *output)
416 {
417 int32_t ret = OpensslEvpCipherUpdate(data->ctx, NULL, (int *)&output->len, data->aad, data->aadLen);
418 if (ret != HCF_OPENSSL_SUCCESS) {
419 HcfPrintOpensslError();
420 LOGE("aad cipher update failed!");
421 return HCF_ERR_CRYPTO_OPERATION;
422 }
423 ret = OpensslEvpCipherUpdate(data->ctx, output->data, (int *)&output->len, input->data, input->len);
424 if (ret != HCF_OPENSSL_SUCCESS) {
425 HcfPrintOpensslError();
426 LOGE("gcm cipher update failed!");
427 return HCF_ERR_CRYPTO_OPERATION;
428 }
429 return HCF_SUCCESS;
430 }
431
EngineUpdate(HcfCipherGeneratorSpi * self,HcfBlob * input,HcfBlob * output)432 static HcfResult EngineUpdate(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfBlob *output)
433 {
434 if ((self == NULL) || (input == NULL) || (output == NULL)) {
435 LOGE("Invalid input parameter!");
436 return HCF_INVALID_PARAMS;
437 }
438 if (!HcfIsClassMatch((HcfObjectBase *)self, self->base.getClass())) {
439 LOGE("Class is not match.");
440 return HCF_INVALID_PARAMS;
441 }
442
443 HcfCipherSm4GeneratorSpiOpensslImpl *cipherImpl = (HcfCipherSm4GeneratorSpiOpensslImpl *)self;
444 CipherData *data = cipherImpl->cipherData;
445 if (data == NULL) {
446 LOGE("cipherData is null!");
447 return HCF_INVALID_PARAMS;
448 }
449 bool isUpdateInput = false;
450 HcfResult ret = AllocateOutput(input, output, &isUpdateInput);
451 if (ret != HCF_SUCCESS) {
452 LOGE("AllocateOutput failed!");
453 return ret;
454 }
455
456 if (!data->aead) {
457 ret = CommonUpdate(data, input, output);
458 } else {
459 ret = AeadUpdate(data, cipherImpl->attr.mode, input, output);
460 }
461 if (ret != HCF_SUCCESS) {
462 HcfBlobDataClearAndFree(output);
463 FreeCipherData(&(cipherImpl->cipherData));
464 }
465 data->aead = false;
466 FreeRedundantOutput(output);
467 return ret;
468 }
469
AllocateGcmOutput(CipherData * data,HcfBlob * input,HcfBlob * output,bool * isUpdateInput)470 static HcfResult AllocateGcmOutput(CipherData *data, HcfBlob *input, HcfBlob *output, bool *isUpdateInput)
471 {
472 uint32_t outLen = 0;
473 if (HcfIsBlobValid(input)) {
474 outLen += input->len;
475 *isUpdateInput = true;
476 }
477 uint32_t authTagLen = (data->enc == ENCRYPT_MODE) ? GCM_TAG_SIZE : 0;
478 outLen += data->updateLen + authTagLen + SM4_BLOCK_SIZE;
479 if (outLen == 0) {
480 LOGE("output size is invaild!");
481 return HCF_INVALID_PARAMS;
482 }
483 output->data = (uint8_t *)HcfMalloc(outLen, 0);
484 if (output->data == NULL) {
485 LOGE("malloc output failed!");
486 return HCF_ERR_MALLOC;
487 }
488 output->len = outLen;
489 return HCF_SUCCESS;
490 }
491
GcmDecryptDoFinal(CipherData * data,HcfBlob * input,HcfBlob * output,uint32_t len)492 static HcfResult GcmDecryptDoFinal(CipherData *data, HcfBlob *input, HcfBlob *output, uint32_t len)
493 {
494 if (data->tag == NULL) {
495 LOGE("gcm decrypt has not AuthTag!");
496 return HCF_INVALID_PARAMS;
497 }
498 int32_t ret = OpensslEvpCipherCtxCtrl(data->ctx, EVP_CTRL_AEAD_SET_TAG, data->tagLen, (void *)data->tag);
499 if (ret != HCF_OPENSSL_SUCCESS) {
500 HcfPrintOpensslError();
501 LOGE("gcm decrypt set AuthTag failed!");
502 return HCF_ERR_CRYPTO_OPERATION;
503 }
504 ret = OpensslEvpCipherFinalEx(data->ctx, output->data + len, (int *)&output->len);
505 if (ret != HCF_OPENSSL_SUCCESS) {
506 HcfPrintOpensslError();
507 LOGE("EVP_CipherFinal_ex failed!");
508 return HCF_ERR_CRYPTO_OPERATION;
509 }
510 output->len = output->len + len;
511 return HCF_SUCCESS;
512 }
513
GcmEncryptDoFinal(CipherData * data,HcfBlob * input,HcfBlob * output,uint32_t len)514 static HcfResult GcmEncryptDoFinal(CipherData *data, HcfBlob *input, HcfBlob *output, uint32_t len)
515 {
516 int32_t ret = OpensslEvpCipherFinalEx(data->ctx, output->data + len, (int *)&output->len);
517 if (ret != HCF_OPENSSL_SUCCESS) {
518 HcfPrintOpensslError();
519 LOGE("EVP_CipherFinal_ex failed!");
520 return HCF_ERR_CRYPTO_OPERATION;
521 }
522 output->len += len;
523 ret = OpensslEvpCipherCtxCtrl(data->ctx, EVP_CTRL_AEAD_GET_TAG, data->tagLen,
524 output->data + output->len);
525 if (ret != HCF_OPENSSL_SUCCESS) {
526 HcfPrintOpensslError();
527 LOGE("get AuthTag failed!");
528 return HCF_ERR_CRYPTO_OPERATION;
529 }
530 output->len += data->tagLen;
531 return HCF_SUCCESS;
532 }
533
GcmDoFinal(CipherData * data,HcfBlob * input,HcfBlob * output)534 static HcfResult GcmDoFinal(CipherData *data, HcfBlob *input, HcfBlob *output)
535 {
536 uint32_t len = 0;
537 bool isUpdateInput = false;
538 HcfResult res = AllocateGcmOutput(data, input, output, &isUpdateInput);
539 if (res != HCF_SUCCESS) {
540 LOGE("AllocateGcmOutput failed!");
541 return res;
542 }
543
544 if (isUpdateInput) {
545 if (data->aad != NULL && data->aadLen != 0) {
546 HcfResult result = AeadUpdate(data, HCF_ALG_MODE_GCM, input, output);
547 if (result != HCF_SUCCESS) {
548 LOGE("AeadUpdate failed!");
549 return result;
550 }
551 } else {
552 HcfResult result = CommonUpdate(data, input, output);
553 if (result != HCF_SUCCESS) {
554 LOGE("No aad update failed!");
555 return result;
556 }
557 }
558 len = output->len;
559 }
560 if (data->enc == ENCRYPT_MODE) {
561 return GcmEncryptDoFinal(data, input, output, len);
562 } else if (data->enc == DECRYPT_MODE) {
563 return GcmDecryptDoFinal(data, input, output, len);
564 } else {
565 return HCF_INVALID_PARAMS;
566 }
567 }
568
CommonDoFinal(CipherData * data,HcfBlob * input,HcfBlob * output)569 static HcfResult CommonDoFinal(CipherData *data, HcfBlob *input, HcfBlob *output)
570 {
571 int32_t ret;
572 uint32_t len = 0;
573 bool isUpdateInput = false;
574 HcfResult res = AllocateOutput(input, output, &isUpdateInput);
575 if (res != HCF_SUCCESS) {
576 LOGE("AllocateOutput failed!");
577 return res;
578 }
579 if (isUpdateInput) {
580 ret = OpensslEvpCipherUpdate(data->ctx, output->data, (int*)&output->len,
581 input->data, input->len);
582 if (ret != HCF_OPENSSL_SUCCESS) {
583 HcfPrintOpensslError();
584 LOGE("EVP_CipherUpdate failed!");
585 return HCF_ERR_CRYPTO_OPERATION;
586 }
587 len += output->len;
588 }
589 ret = OpensslEvpCipherFinalEx(data->ctx, output->data + len, (int *)&output->len);
590 if (ret != HCF_OPENSSL_SUCCESS) {
591 HcfPrintOpensslError();
592 LOGE("EVP_CipherFinal_ex failed!");
593 return HCF_ERR_CRYPTO_OPERATION;
594 }
595 output->len += len;
596 return HCF_SUCCESS;
597 }
598
EngineDoFinal(HcfCipherGeneratorSpi * self,HcfBlob * input,HcfBlob * output)599 static HcfResult EngineDoFinal(HcfCipherGeneratorSpi* self, HcfBlob* input, HcfBlob* output)
600 {
601 if ((self == NULL) || (output == NULL)) { /* input maybe is null */
602 LOGE("Invalid input parameter.");
603 return HCF_INVALID_PARAMS;
604 }
605 if (!HcfIsClassMatch((HcfObjectBase*)self, self->base.getClass())) {
606 LOGE("Class is not match.");
607 return HCF_INVALID_PARAMS;
608 }
609
610 HcfResult ret = HCF_ERR_CRYPTO_OPERATION;
611 HcfCipherSm4GeneratorSpiOpensslImpl *cipherImpl = (HcfCipherSm4GeneratorSpiOpensslImpl *)self;
612 CipherData *data = cipherImpl->cipherData;
613 if (data == NULL) {
614 LOGE("cipherData is null!");
615 return HCF_INVALID_PARAMS;
616 }
617
618 HcfAlgParaValue mode = cipherImpl->attr.mode;
619 if (mode == HCF_ALG_MODE_GCM) {
620 ret = GcmDoFinal(data, input, output);
621 } else { /* only ECB CBC CTR CFB OFB support */
622 ret = CommonDoFinal(data, input, output);
623 }
624
625 FreeCipherData(&(cipherImpl->cipherData));
626 if (ret != HCF_SUCCESS) {
627 HcfBlobDataClearAndFree(output);
628 }
629 FreeRedundantOutput(output);
630 return ret;
631 }
632
EngineSm4GeneratorDestroy(HcfObjectBase * self)633 static void EngineSm4GeneratorDestroy(HcfObjectBase *self)
634 {
635 if (self == NULL) {
636 return;
637 }
638 if (!HcfIsClassMatch(self, self->getClass())) {
639 LOGE("Class is not match.");
640 return;
641 }
642
643 HcfCipherSm4GeneratorSpiOpensslImpl *impl = (HcfCipherSm4GeneratorSpiOpensslImpl *)self;
644 FreeCipherData(&(impl->cipherData));
645 HcfFree(impl);
646 }
647
GetSm4CipherSpecString(HcfCipherGeneratorSpi * self,CipherSpecItem item,char ** returnString)648 static HcfResult GetSm4CipherSpecString(HcfCipherGeneratorSpi *self, CipherSpecItem item, char **returnString)
649 {
650 (void)self;
651 (void)item;
652 (void)returnString;
653 return HCF_NOT_SUPPORT;
654 }
655
GetSm4CipherSpecUint8Array(HcfCipherGeneratorSpi * self,CipherSpecItem item,HcfBlob * returnUint8Array)656 static HcfResult GetSm4CipherSpecUint8Array(HcfCipherGeneratorSpi *self, CipherSpecItem item, HcfBlob *returnUint8Array)
657 {
658 (void)self;
659 (void)item;
660 (void)returnUint8Array;
661 return HCF_NOT_SUPPORT;
662 }
663
SetSm4CipherSpecUint8Array(HcfCipherGeneratorSpi * self,CipherSpecItem item,HcfBlob blob)664 static HcfResult SetSm4CipherSpecUint8Array(HcfCipherGeneratorSpi *self, CipherSpecItem item, HcfBlob blob)
665 {
666 (void)self;
667 (void)item;
668 (void)blob;
669 return HCF_NOT_SUPPORT;
670 }
671
HcfCipherSm4GeneratorSpiCreate(CipherAttr * attr,HcfCipherGeneratorSpi ** generator)672 HcfResult HcfCipherSm4GeneratorSpiCreate(CipherAttr *attr, HcfCipherGeneratorSpi **generator)
673 {
674 if (attr == NULL || generator == NULL) {
675 LOGE("Invalid input parameter.");
676 return HCF_INVALID_PARAMS;
677 }
678 HcfCipherSm4GeneratorSpiOpensslImpl *returnImpl = (HcfCipherSm4GeneratorSpiOpensslImpl *)HcfMalloc(
679 sizeof(HcfCipherSm4GeneratorSpiOpensslImpl), 0);
680 if (returnImpl == NULL) {
681 LOGE("Failed to allocate returnImpl memroy!");
682 return HCF_ERR_MALLOC;
683 }
684 (void)memcpy_s(&returnImpl->attr, sizeof(CipherAttr), attr, sizeof(CipherAttr));
685 returnImpl->base.init = EngineCipherInit;
686 returnImpl->base.update = EngineUpdate;
687 returnImpl->base.doFinal = EngineDoFinal;
688 returnImpl->base.getCipherSpecString = GetSm4CipherSpecString;
689 returnImpl->base.getCipherSpecUint8Array = GetSm4CipherSpecUint8Array;
690 returnImpl->base.setCipherSpecUint8Array = SetSm4CipherSpecUint8Array;
691 returnImpl->base.base.destroy = EngineSm4GeneratorDestroy;
692 returnImpl->base.base.getClass = GetSm4GeneratorClass;
693
694 *generator = (HcfCipherGeneratorSpi *)returnImpl;
695 return HCF_SUCCESS;
696 }
697