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