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 "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 CCM_AAD_MAX_LEN 2048
29 #define GCM_IV_MIN_LEN 1
30 #define GCM_IV_MAX_LEN 128
31 #define CCM_IV_MIN_LEN 7
32 #define CCM_IV_MAX_LEN 13
33 #define CBC_CTR_OFB_CFB_IV_LEN 16
34 #define AES_BLOCK_SIZE 16
35 #define GCM_TAG_SIZE 16
36 #define CCM_TAG_SIZE 12
37 #define AES_SIZE_128 16
38 #define AES_SIZE_192 24
39 #define AES_SIZE_256 32
40 
41 typedef struct {
42     HcfCipherGeneratorSpi base;
43     CipherAttr attr;
44     CipherData *cipherData;
45 } HcfCipherAesGeneratorSpiOpensslImpl;
46 
GetAesGeneratorClass(void)47 static const char *GetAesGeneratorClass(void)
48 {
49     return OPENSSL_AES_CIPHER_CLASS;
50 }
51 
CipherEcbType(SymKeyImpl * symKey)52 static const EVP_CIPHER *CipherEcbType(SymKeyImpl *symKey)
53 {
54     if (symKey->keyMaterial.len == AES_SIZE_192) {
55         return OpensslEvpAes192Ecb();
56     } else if (symKey->keyMaterial.len == AES_SIZE_256) {
57         return OpensslEvpAes256Ecb();
58     } else {
59         return OpensslEvpAes128Ecb();
60     }
61 }
62 
CipherCbcType(SymKeyImpl * symKey)63 static const EVP_CIPHER *CipherCbcType(SymKeyImpl *symKey)
64 {
65     if (symKey->keyMaterial.len == AES_SIZE_192) {
66         return OpensslEvpAes192Cbc();
67     } else if (symKey->keyMaterial.len == AES_SIZE_256) {
68         return OpensslEvpAes256Cbc();
69     } else {
70         return OpensslEvpAes128Cbc();
71     }
72 }
73 
CipherCtrType(SymKeyImpl * symKey)74 static const EVP_CIPHER *CipherCtrType(SymKeyImpl *symKey)
75 {
76     if (symKey->keyMaterial.len == AES_SIZE_192) {
77         return OpensslEvpAes192Ctr();
78     } else if (symKey->keyMaterial.len == AES_SIZE_256) {
79         return OpensslEvpAes256Ctr();
80     } else {
81         return OpensslEvpAes128Ctr();
82     }
83 }
84 
CipherOfbType(SymKeyImpl * symKey)85 static const EVP_CIPHER *CipherOfbType(SymKeyImpl *symKey)
86 {
87     if (symKey->keyMaterial.len == AES_SIZE_192) {
88         return OpensslEvpAes192Ofb();
89     } else if (symKey->keyMaterial.len == AES_SIZE_256) {
90         return OpensslEvpAes256Ofb();
91     } else {
92         return OpensslEvpAes128Ofb();
93     }
94 }
95 
CipherCfbType(SymKeyImpl * symKey)96 static const EVP_CIPHER *CipherCfbType(SymKeyImpl *symKey)
97 {
98     if (symKey->keyMaterial.len == AES_SIZE_192) {
99         return OpensslEvpAes192Cfb();
100     } else if (symKey->keyMaterial.len == AES_SIZE_256) {
101         return OpensslEvpAes256Cfb();
102     } else {
103         return OpensslEvpAes128Cfb();
104     }
105 }
106 
CipherCfb1Type(SymKeyImpl * symKey)107 static const EVP_CIPHER *CipherCfb1Type(SymKeyImpl *symKey)
108 {
109     if (symKey->keyMaterial.len == AES_SIZE_192) {
110         return OpensslEvpAes192Cfb1();
111     } else if (symKey->keyMaterial.len == AES_SIZE_256) {
112         return OpensslEvpAes256Cfb1();
113     } else {
114         return OpensslEvpAes128Cfb1();
115     }
116 }
117 
CipherCfb128Type(SymKeyImpl * symKey)118 static const EVP_CIPHER *CipherCfb128Type(SymKeyImpl *symKey)
119 {
120     if (symKey->keyMaterial.len == AES_SIZE_192) {
121         return OpensslEvpAes192Cfb128();
122     } else if (symKey->keyMaterial.len == AES_SIZE_256) {
123         return OpensslEvpAes256Cfb128();
124     } else {
125         return OpensslEvpAes128Cfb128();
126     }
127 }
128 
CipherCfb8Type(SymKeyImpl * symKey)129 static const EVP_CIPHER *CipherCfb8Type(SymKeyImpl *symKey)
130 {
131     if (symKey->keyMaterial.len == AES_SIZE_192) {
132         return OpensslEvpAes192Cfb8();
133     } else if (symKey->keyMaterial.len == AES_SIZE_256) {
134         return OpensslEvpAes256Cfb8();
135     } else {
136         return OpensslEvpAes128Cfb8();
137     }
138 }
139 
140 
CipherCcmType(SymKeyImpl * symKey)141 static const EVP_CIPHER *CipherCcmType(SymKeyImpl *symKey)
142 {
143     if (symKey->keyMaterial.len == AES_SIZE_192) {
144         return OpensslEvpAes192Ccm();
145     } else if (symKey->keyMaterial.len == AES_SIZE_256) {
146         return OpensslEvpAes256Ccm();
147     } else {
148         return OpensslEvpAes128Ccm();
149     }
150 }
151 
CipherGcmType(SymKeyImpl * symKey)152 static const EVP_CIPHER *CipherGcmType(SymKeyImpl *symKey)
153 {
154     if (symKey->keyMaterial.len == AES_SIZE_192) {
155         return OpensslEvpAes192Gcm();
156     } else if (symKey->keyMaterial.len == AES_SIZE_256) {
157         return OpensslEvpAes256Gcm();
158     } else {
159         return OpensslEvpAes128Gcm();
160     }
161 }
162 
DefaultCiherType(SymKeyImpl * symKey)163 static const EVP_CIPHER *DefaultCiherType(SymKeyImpl *symKey)
164 {
165     return CipherEcbType(symKey);
166 }
167 
GetCipherType(HcfCipherAesGeneratorSpiOpensslImpl * impl,SymKeyImpl * symKey)168 static const EVP_CIPHER *GetCipherType(HcfCipherAesGeneratorSpiOpensslImpl *impl, SymKeyImpl *symKey)
169 {
170     switch (impl->attr.mode) {
171         case HCF_ALG_MODE_ECB:
172             return CipherEcbType(symKey);
173         case HCF_ALG_MODE_CBC:
174             return CipherCbcType(symKey);
175         case HCF_ALG_MODE_CTR:
176             return CipherCtrType(symKey);
177         case HCF_ALG_MODE_OFB:
178             return CipherOfbType(symKey);
179         case HCF_ALG_MODE_CFB:
180             return CipherCfbType(symKey);
181         case HCF_ALG_MODE_CFB1:
182             return CipherCfb1Type(symKey);
183         case HCF_ALG_MODE_CFB8:
184             return CipherCfb8Type(symKey);
185         case HCF_ALG_MODE_CFB128:
186             return CipherCfb128Type(symKey);
187         case HCF_ALG_MODE_CCM:
188             return CipherCcmType(symKey);
189         case HCF_ALG_MODE_GCM:
190             return CipherGcmType(symKey);
191         default:
192             break;
193     }
194     return DefaultCiherType(symKey);
195 }
196 
IsGcmParamsValid(HcfGcmParamsSpec * params)197 static bool IsGcmParamsValid(HcfGcmParamsSpec *params)
198 {
199     if (params == NULL) {
200         LOGE("params is null!");
201         return false;
202     }
203     if ((params->iv.data == NULL) || (params->iv.len < GCM_IV_MIN_LEN) || (params->iv.len > GCM_IV_MAX_LEN)) {
204         LOGE("iv is invalid!");
205         return false;
206     }
207     if ((params->tag.data == NULL) || (params->tag.len == 0)) {
208         LOGE("tag is invalid!");
209         return false;
210     }
211     return true;
212 }
213 
IsCcmParamsValid(HcfCcmParamsSpec * params)214 static bool IsCcmParamsValid(HcfCcmParamsSpec *params)
215 {
216     if (params == NULL) {
217         LOGE("params is null!");
218         return false;
219     }
220     if ((params->aad.data == NULL) || (params->aad.len == 0) || (params->aad.len > CCM_AAD_MAX_LEN)) {
221         LOGE("aad is invalid!");
222         return false;
223     }
224     if ((params->iv.data == NULL) || (params->iv.len < CCM_IV_MIN_LEN) || (params->iv.len > CCM_IV_MAX_LEN)) {
225         LOGE("iv is invalid!");
226         return false;
227     }
228     if ((params->tag.data == NULL) || (params->tag.len == 0)) {
229         LOGE("tag is invalid!");
230         return false;
231     }
232     return true;
233 }
234 
IsIvParamsValid(HcfIvParamsSpec * params)235 static HcfResult IsIvParamsValid(HcfIvParamsSpec *params)
236 {
237     if (params == NULL) {
238         LOGE("params is null!");
239         return HCF_INVALID_PARAMS;
240     }
241     if ((params->iv.data == NULL) || (params->iv.len != CBC_CTR_OFB_CFB_IV_LEN)) {
242         LOGE("iv is invalid!");
243         return HCF_INVALID_PARAMS;
244     }
245     return HCF_SUCCESS;
246 }
247 
InitAadAndTagFromGcmParams(enum HcfCryptoMode opMode,HcfGcmParamsSpec * params,CipherData * data)248 static HcfResult InitAadAndTagFromGcmParams(enum HcfCryptoMode opMode, HcfGcmParamsSpec *params, CipherData *data)
249 {
250     if (!IsGcmParamsValid(params)) {
251         LOGE("gcm params is invalid!");
252         return HCF_INVALID_PARAMS;
253     }
254 
255     if (params->aad.data != NULL && params->aad.len != 0) {
256         data->aad = (uint8_t *)HcfMalloc(params->aad.len, 0);
257         if (data->aad == NULL) {
258             LOGE("aad malloc failed!");
259             return HCF_ERR_MALLOC;
260         }
261         (void)memcpy_s(data->aad, params->aad.len, params->aad.data, params->aad.len);
262         data->aadLen = params->aad.len;
263         data->aead = true;
264     } else {
265         data->aad = NULL;
266         data->aadLen = 0;
267         data->aead = false;
268     }
269     data->tagLen = params->tag.len;
270     if (opMode == ENCRYPT_MODE) {
271         return HCF_SUCCESS;
272     }
273     data->tag = (uint8_t *)HcfMalloc(params->tag.len, 0);
274     if (data->tag == NULL) {
275         HcfFree(data->aad);
276         data->aad = NULL;
277         LOGE("tag malloc failed!");
278         return HCF_ERR_MALLOC;
279     }
280     (void)memcpy_s(data->tag, params->tag.len, params->tag.data, params->tag.len);
281     return HCF_SUCCESS;
282 }
283 
InitAadAndTagFromCcmParams(enum HcfCryptoMode opMode,HcfCcmParamsSpec * params,CipherData * data)284 static HcfResult InitAadAndTagFromCcmParams(enum HcfCryptoMode opMode, HcfCcmParamsSpec *params, CipherData *data)
285 {
286     if (!IsCcmParamsValid(params)) {
287         LOGE("gcm params is invalid!");
288         return HCF_INVALID_PARAMS;
289     }
290 
291     data->aad = (uint8_t *)HcfMalloc(params->aad.len, 0);
292     if (data->aad == NULL) {
293         LOGE("aad malloc failed!");
294         return HCF_ERR_MALLOC;
295     }
296     (void)memcpy_s(data->aad, params->aad.len, params->aad.data, params->aad.len);
297     data->aadLen = params->aad.len;
298     data->aead = true;
299 
300     data->tagLen = params->tag.len;
301     if (opMode == ENCRYPT_MODE) {
302         return HCF_SUCCESS;
303     }
304     data->tag = (uint8_t *)HcfMalloc(params->tag.len, 0);
305     if (data->tag == NULL) {
306         HcfFree(data->aad);
307         data->aad = NULL;
308         LOGE("tag malloc failed!");
309         return HCF_ERR_MALLOC;
310     }
311     (void)memcpy_s(data->tag, params->tag.len, params->tag.data, params->tag.len);
312     return HCF_SUCCESS;
313 }
314 
InitCipherData(HcfCipherGeneratorSpi * self,enum HcfCryptoMode opMode,HcfParamsSpec * params,CipherData ** cipherData)315 static HcfResult InitCipherData(HcfCipherGeneratorSpi *self, enum HcfCryptoMode opMode,
316     HcfParamsSpec *params, CipherData **cipherData)
317 {
318     HcfResult ret = HCF_ERR_MALLOC;
319     *cipherData = (CipherData *)HcfMalloc(sizeof(CipherData), 0);
320     if (*cipherData == NULL) {
321         LOGE("malloc is failed!");
322         return ret;
323     }
324     HcfCipherAesGeneratorSpiOpensslImpl *cipherImpl = (HcfCipherAesGeneratorSpiOpensslImpl *)self;
325     HcfAlgParaValue mode = cipherImpl->attr.mode;
326 
327     (*cipherData)->enc = opMode;
328     (*cipherData)->ctx = OpensslEvpCipherCtxNew();
329     if ((*cipherData)->ctx == NULL) {
330         HcfPrintOpensslError();
331         LOGD("[error] Failed to allocate ctx memory!");
332         goto clearup;
333     }
334 
335     ret = HCF_SUCCESS;
336     switch (mode) {
337         case HCF_ALG_MODE_CBC:
338         case HCF_ALG_MODE_CTR:
339         case HCF_ALG_MODE_OFB:
340         case HCF_ALG_MODE_CFB:
341         case HCF_ALG_MODE_CFB1:
342         case HCF_ALG_MODE_CFB8:
343         case HCF_ALG_MODE_CFB128:
344             ret = IsIvParamsValid((HcfIvParamsSpec *)params);
345             break;
346         case HCF_ALG_MODE_CCM:
347             ret = InitAadAndTagFromCcmParams(opMode, (HcfCcmParamsSpec *)params, *cipherData);
348             break;
349         case HCF_ALG_MODE_GCM:
350             ret = InitAadAndTagFromGcmParams(opMode, (HcfGcmParamsSpec *)params, *cipherData);
351             break;
352         default:
353             break;
354     }
355     if (ret != HCF_SUCCESS) {
356         LOGE("gcm or ccm or iv init failed!");
357         goto clearup;
358     }
359     return ret;
360 clearup:
361     FreeCipherData(cipherData);
362     return ret;
363 }
364 
SetCipherAttribute(HcfCipherAesGeneratorSpiOpensslImpl * cipherImpl,SymKeyImpl * keyImpl,int enc,HcfParamsSpec * params)365 static bool SetCipherAttribute(HcfCipherAesGeneratorSpiOpensslImpl *cipherImpl, SymKeyImpl *keyImpl,
366     int enc, HcfParamsSpec *params)
367 {
368     CipherData *data = cipherImpl->cipherData;
369     HcfAlgParaValue mode = cipherImpl->attr.mode;
370     if (mode != HCF_ALG_MODE_GCM) {
371         if (OpensslEvpCipherInit(data->ctx, GetCipherType(cipherImpl, keyImpl), keyImpl->keyMaterial.data,
372             GetIv(params), enc) != HCF_OPENSSL_SUCCESS) {
373             HcfPrintOpensslError();
374             LOGD("[error] EVP_CipherInit failed!");
375             return false;
376         }
377         return true;
378     }
379     if (OpensslEvpCipherInit(data->ctx, GetCipherType(cipherImpl, keyImpl),
380         NULL, NULL, enc) != HCF_OPENSSL_SUCCESS) {
381         HcfPrintOpensslError();
382         LOGD("[error] EVP_CipherInit failed!");
383         return false;
384     }
385     if (OpensslEvpCipherCtxCtrl(data->ctx, EVP_CTRL_AEAD_SET_IVLEN,
386         GetIvLen(params), NULL) != HCF_OPENSSL_SUCCESS) {
387         HcfPrintOpensslError();
388         LOGD("[error]EVP_Cipher set iv len failed!");
389         return false;
390     }
391     if (OpensslEvpCipherInit(data->ctx, NULL, keyImpl->keyMaterial.data,
392         GetIv(params), enc) != HCF_OPENSSL_SUCCESS) {
393         HcfPrintOpensslError();
394         LOGD("[error]EVP_CipherInit failed!");
395         return false;
396     }
397     return true;
398 }
399 
EngineCipherInit(HcfCipherGeneratorSpi * self,enum HcfCryptoMode opMode,HcfKey * key,HcfParamsSpec * params)400 static HcfResult EngineCipherInit(HcfCipherGeneratorSpi *self, enum HcfCryptoMode opMode,
401     HcfKey *key, HcfParamsSpec *params)
402 {
403     // params spec may be null, do not check
404     if ((self == NULL) || (key == NULL)) {
405         LOGE("Invalid input parameter!");
406         return HCF_INVALID_PARAMS;
407     }
408     if ((!HcfIsClassMatch((const HcfObjectBase *)self, GetAesGeneratorClass())) ||
409         (!HcfIsClassMatch((const HcfObjectBase *)key, OPENSSL_SYM_KEY_CLASS))) {
410         return HCF_INVALID_PARAMS;
411     }
412     HcfCipherAesGeneratorSpiOpensslImpl *cipherImpl = (HcfCipherAesGeneratorSpiOpensslImpl *)self;
413     SymKeyImpl *keyImpl = (SymKeyImpl *)key;
414     int enc = (opMode == ENCRYPT_MODE) ? 1 : 0;
415     cipherImpl->attr.keySize = keyImpl->keyMaterial.len;
416     if (InitCipherData(self, opMode, params, &(cipherImpl->cipherData)) != HCF_SUCCESS) {
417         LOGE("InitCipherData failed!");
418         return HCF_INVALID_PARAMS;
419     }
420 
421     CipherData *data = cipherImpl->cipherData;
422     HcfResult ret = HCF_ERR_CRYPTO_OPERATION;
423     if (!SetCipherAttribute(cipherImpl, keyImpl, enc, params)) {
424         LOGD("[error]Set cipher attribute failed!");
425         goto clearup;
426     }
427 
428     int32_t padding = (cipherImpl->attr.paddingMode == HCF_ALG_NOPADDING) ? 0 : EVP_PADDING_PKCS7;
429 
430     if (OpensslEvpCipherCtxSetPadding(data->ctx, padding) != HCF_OPENSSL_SUCCESS) {
431         HcfPrintOpensslError();
432         LOGD("[error]set padding failed!");
433         goto clearup;
434     }
435 
436     if (opMode == ENCRYPT_MODE || cipherImpl->attr.mode != HCF_ALG_MODE_CCM) {
437         return HCF_SUCCESS;
438     }
439     /* ccm decrypt need set tag */
440     if (OpensslEvpCipherCtxCtrl(data->ctx, EVP_CTRL_AEAD_SET_TAG, GetCcmTagLen(params),
441         GetCcmTag(params)) != HCF_OPENSSL_SUCCESS) {
442         HcfPrintOpensslError();
443         LOGD("[error]set AuthTag failed!");
444         goto clearup;
445     }
446     return HCF_SUCCESS;
447 clearup:
448     FreeCipherData(&(cipherImpl->cipherData));
449     return ret;
450 }
451 
CommonUpdate(CipherData * data,HcfBlob * input,HcfBlob * output)452 static HcfResult CommonUpdate(CipherData *data, HcfBlob *input, HcfBlob *output)
453 {
454     int32_t ret = OpensslEvpCipherUpdate(data->ctx, output->data, (int *)&output->len,
455         input->data, input->len);
456     if (ret != HCF_OPENSSL_SUCCESS) {
457         HcfPrintOpensslError();
458         LOGD("[error]cipher update failed!");
459         return HCF_ERR_CRYPTO_OPERATION;
460     }
461     return HCF_SUCCESS;
462 }
463 
AeadUpdate(CipherData * data,HcfAlgParaValue mode,HcfBlob * input,HcfBlob * output)464 static HcfResult AeadUpdate(CipherData *data, HcfAlgParaValue mode, HcfBlob *input, HcfBlob *output)
465 {
466     if (mode == HCF_ALG_MODE_CCM) {
467         if (OpensslEvpCipherUpdate(data->ctx, NULL, (int *)&output->len, NULL, input->len) != HCF_OPENSSL_SUCCESS) {
468             HcfPrintOpensslError();
469             LOGD("[error]ccm cipher update failed!");
470             return HCF_ERR_CRYPTO_OPERATION;
471         }
472     }
473 
474     int32_t ret = OpensslEvpCipherUpdate(data->ctx, NULL, (int *)&output->len, data->aad, data->aadLen);
475     if (ret != HCF_OPENSSL_SUCCESS) {
476         HcfPrintOpensslError();
477         LOGD("[error]aad cipher update failed!");
478         return HCF_ERR_CRYPTO_OPERATION;
479     }
480     ret = OpensslEvpCipherUpdate(data->ctx, output->data, (int *)&output->len, input->data, input->len);
481     if (ret != HCF_OPENSSL_SUCCESS) {
482         HcfPrintOpensslError();
483         LOGD("[error]gcm cipher update failed!");
484         return HCF_ERR_CRYPTO_OPERATION;
485     }
486     return HCF_SUCCESS;
487 }
488 
AllocateOutput(HcfBlob * input,HcfBlob * output,bool * isUpdateInput)489 static HcfResult AllocateOutput(HcfBlob *input, HcfBlob *output, bool *isUpdateInput)
490 {
491     uint32_t outLen = AES_BLOCK_SIZE + AES_BLOCK_SIZE;
492     if (HcfIsBlobValid(input)) {
493         outLen += input->len;
494         *isUpdateInput = true;
495     }
496     output->data = (uint8_t *)HcfMalloc(outLen, 0);
497     if (output->data == NULL) {
498         LOGE("malloc output failed!");
499         return HCF_ERR_MALLOC;
500     }
501     output->len = outLen;
502     return HCF_SUCCESS;
503 }
504 
EngineUpdate(HcfCipherGeneratorSpi * self,HcfBlob * input,HcfBlob * output)505 static HcfResult EngineUpdate(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfBlob *output)
506 {
507     if ((self == NULL) || (input == NULL) || (output == NULL)) {
508         LOGE("Invalid input parameter!");
509         return HCF_INVALID_PARAMS;
510     }
511     if (!HcfIsClassMatch((const HcfObjectBase *)self, GetAesGeneratorClass())) {
512         LOGE("Class is not match.");
513         return HCF_INVALID_PARAMS;
514     }
515 
516     HcfCipherAesGeneratorSpiOpensslImpl *cipherImpl = (HcfCipherAesGeneratorSpiOpensslImpl *)self;
517     CipherData *data = cipherImpl->cipherData;
518     if (data == NULL) {
519         LOGE("cipherData is null!");
520         return HCF_INVALID_PARAMS;
521     }
522     bool isUpdateInput = false;
523     HcfResult ret = AllocateOutput(input, output, &isUpdateInput);
524     if (ret != HCF_SUCCESS) {
525         LOGE("AllocateOutput failed!");
526         return ret;
527     }
528 
529     if (!data->aead) {
530         ret = CommonUpdate(data, input, output);
531     } else {
532         ret = AeadUpdate(data, cipherImpl->attr.mode, input, output);
533     }
534     if (ret != HCF_SUCCESS) {
535         HcfBlobDataClearAndFree(output);
536         FreeCipherData(&(cipherImpl->cipherData));
537     }
538     data->aead = false;
539     FreeRedundantOutput(output);
540     return ret;
541 }
542 
CommonDoFinal(CipherData * data,HcfBlob * input,HcfBlob * output)543 static HcfResult CommonDoFinal(CipherData *data, HcfBlob *input, HcfBlob *output)
544 {
545     int32_t ret;
546     uint32_t len = 0;
547     bool isUpdateInput = false;
548     HcfResult res = AllocateOutput(input, output, &isUpdateInput);
549     if (res != HCF_SUCCESS) {
550         LOGE("AllocateOutput failed!");
551         return res;
552     }
553     if (isUpdateInput) {
554         ret = OpensslEvpCipherUpdate(data->ctx, output->data, (int32_t *)&len, input->data, input->len);
555         if (ret != HCF_OPENSSL_SUCCESS) {
556             HcfPrintOpensslError();
557             LOGD("[error]EVP_CipherUpdate failed!");
558             return HCF_ERR_CRYPTO_OPERATION;
559         }
560     }
561     ret = OpensslEvpCipherFinalEx(data->ctx, output->data + len, (int *)&output->len);
562     if (ret != HCF_OPENSSL_SUCCESS) {
563         HcfPrintOpensslError();
564         LOGD("[error]EVP_CipherFinal_ex failed!");
565         return HCF_ERR_CRYPTO_OPERATION;
566     }
567     output->len += len;
568     return HCF_SUCCESS;
569 }
570 
AllocateCcmOutput(CipherData * data,HcfBlob * input,HcfBlob * output,bool * isUpdateInput)571 static HcfResult AllocateCcmOutput(CipherData *data, HcfBlob *input, HcfBlob *output, bool *isUpdateInput)
572 {
573     uint32_t outLen = 0;
574     if (HcfIsBlobValid(input)) {
575         outLen += input->len;
576         *isUpdateInput = true;
577     }
578     uint32_t authTagLen = (data->enc == ENCRYPT_MODE) ? CCM_TAG_SIZE : 0;
579     outLen += authTagLen + AES_BLOCK_SIZE;
580     if (outLen == 0) {
581         LOGE("output size is invaild!");
582         return HCF_INVALID_PARAMS;
583     }
584     output->data = (uint8_t *)HcfMalloc(outLen, 0);
585     if (output->data == NULL) {
586         LOGE("malloc output failed!");
587         return HCF_ERR_MALLOC;
588     }
589     output->len = outLen;
590     return HCF_SUCCESS;
591 }
592 
CcmDecryptDoFinal(HcfBlob * output,bool isUpdateInput)593 static HcfResult CcmDecryptDoFinal(HcfBlob *output, bool isUpdateInput)
594 {
595     if (isUpdateInput) { /* DecryptFinal this does not occur in CCM mode */
596         return HCF_SUCCESS;
597     }
598     if (output->data != NULL) {
599         HcfBlobDataClearAndFree(output);
600     }
601     return HCF_SUCCESS;
602 }
603 
CcmEncryptDoFinal(CipherData * data,HcfBlob * output,uint32_t len)604 static HcfResult CcmEncryptDoFinal(CipherData *data, HcfBlob *output, uint32_t len)
605 {
606     int32_t ret = OpensslEvpCipherCtxCtrl(data->ctx, EVP_CTRL_AEAD_GET_TAG, data->tagLen, output->data + len);
607     if (ret != HCF_OPENSSL_SUCCESS) {
608         HcfPrintOpensslError();
609         LOGD("[error]get AuthTag failed!");
610         return HCF_ERR_CRYPTO_OPERATION;
611     }
612     output->len = data->tagLen + len;
613     return HCF_SUCCESS;
614 }
615 
CcmDoFinal(CipherData * data,HcfBlob * input,HcfBlob * output)616 static HcfResult CcmDoFinal(CipherData *data, HcfBlob *input, HcfBlob *output)
617 {
618     bool isUpdateInput = false;
619     uint32_t len = 0;
620     HcfResult res = AllocateCcmOutput(data, input, output, &isUpdateInput);
621     if (res != HCF_SUCCESS) {
622         LOGE("AllocateCcmOutput failed!");
623         return res;
624     }
625     if (isUpdateInput) {
626         HcfResult result = AeadUpdate(data, HCF_ALG_MODE_CCM, input, output);
627         if (result != HCF_SUCCESS) {
628             LOGE("AeadUpdate failed!");
629             return result;
630         }
631         len = output->len;
632     }
633     if (data->enc == ENCRYPT_MODE) {
634         return CcmEncryptDoFinal(data, output, len);
635     } else if (data->enc == DECRYPT_MODE) {
636         return CcmDecryptDoFinal(output, isUpdateInput);
637     } else {
638         return HCF_INVALID_PARAMS;
639     }
640 }
641 
GcmDecryptDoFinal(CipherData * data,HcfBlob * input,HcfBlob * output,uint32_t len)642 static HcfResult GcmDecryptDoFinal(CipherData *data, HcfBlob *input, HcfBlob *output, uint32_t len)
643 {
644     if (data->tag == NULL) {
645         LOGE("gcm decrypt has not AuthTag!");
646         return HCF_INVALID_PARAMS;
647     }
648     int32_t ret = OpensslEvpCipherCtxCtrl(data->ctx, EVP_CTRL_AEAD_SET_TAG, data->tagLen, (void *)data->tag);
649     if (ret != HCF_OPENSSL_SUCCESS) {
650         HcfPrintOpensslError();
651         LOGD("[error]gcm decrypt set AuthTag failed!");
652         return HCF_ERR_CRYPTO_OPERATION;
653     }
654     ret = OpensslEvpCipherFinalEx(data->ctx, output->data + len, (int *)&output->len);
655     if (ret != HCF_OPENSSL_SUCCESS) {
656         HcfPrintOpensslError();
657         LOGD("[error]EVP_CipherFinal_ex failed!");
658         return HCF_ERR_CRYPTO_OPERATION;
659     }
660     output->len = output->len + len;
661     return HCF_SUCCESS;
662 }
663 
GcmEncryptDoFinal(CipherData * data,HcfBlob * input,HcfBlob * output,uint32_t len)664 static HcfResult GcmEncryptDoFinal(CipherData *data, HcfBlob *input, HcfBlob *output, uint32_t len)
665 {
666     int32_t ret = OpensslEvpCipherFinalEx(data->ctx, output->data + len, (int *)&output->len);
667     if (ret != HCF_OPENSSL_SUCCESS) {
668         HcfPrintOpensslError();
669         LOGD("[error]EVP_CipherFinal_ex failed!");
670         return HCF_ERR_CRYPTO_OPERATION;
671     }
672     output->len += len;
673     ret = OpensslEvpCipherCtxCtrl(data->ctx, EVP_CTRL_AEAD_GET_TAG, data->tagLen,
674         output->data + output->len);
675     if (ret != HCF_OPENSSL_SUCCESS) {
676         HcfPrintOpensslError();
677         LOGD("[error]get AuthTag failed!");
678         return HCF_ERR_CRYPTO_OPERATION;
679     }
680     output->len += data->tagLen;
681     return HCF_SUCCESS;
682 }
683 
AllocateGcmOutput(CipherData * data,HcfBlob * input,HcfBlob * output,bool * isUpdateInput)684 static HcfResult AllocateGcmOutput(CipherData *data, HcfBlob *input, HcfBlob *output, bool *isUpdateInput)
685 {
686     uint32_t outLen = 0;
687     if (HcfIsBlobValid(input)) {
688         outLen += input->len;
689         *isUpdateInput = true;
690     }
691     uint32_t authTagLen = (data->enc == ENCRYPT_MODE) ? GCM_TAG_SIZE : 0;
692     outLen += data->updateLen + authTagLen + AES_BLOCK_SIZE;
693     if (outLen == 0) {
694         LOGE("output size is invaild!");
695         return HCF_INVALID_PARAMS;
696     }
697     output->data = (uint8_t *)HcfMalloc(outLen, 0);
698     if (output->data == NULL) {
699         LOGE("malloc output failed!");
700         return HCF_ERR_MALLOC;
701     }
702     output->len = outLen;
703     return HCF_SUCCESS;
704 }
705 
GcmDoFinal(CipherData * data,HcfBlob * input,HcfBlob * output)706 static HcfResult GcmDoFinal(CipherData *data, HcfBlob *input, HcfBlob *output)
707 {
708     uint32_t len = 0;
709     bool isUpdateInput = false;
710     HcfResult res = AllocateGcmOutput(data, input, output, &isUpdateInput);
711     if (res != HCF_SUCCESS) {
712         LOGE("AllocateGcmOutput failed!");
713         return res;
714     }
715 
716     if (isUpdateInput) {
717         if (data->aad != NULL && data->aadLen != 0) {
718             HcfResult result = AeadUpdate(data, HCF_ALG_MODE_GCM, input, output);
719             if (result != HCF_SUCCESS) {
720                 LOGD("[error]AeadUpdate failed!");
721                 return result;
722             }
723         } else {
724             HcfResult result = CommonUpdate(data, input, output);
725             if (result != HCF_SUCCESS) {
726                 LOGD("[error]No aad update failed!");
727                 return result;
728             }
729         }
730         len = output->len;
731     }
732     if (data->enc == ENCRYPT_MODE) {
733         return GcmEncryptDoFinal(data, input, output, len);
734     } else if (data->enc == DECRYPT_MODE) {
735         return GcmDecryptDoFinal(data, input, output, len);
736     } else {
737         return HCF_INVALID_PARAMS;
738     }
739 }
740 
EngineDoFinal(HcfCipherGeneratorSpi * self,HcfBlob * input,HcfBlob * output)741 static HcfResult EngineDoFinal(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfBlob *output)
742 {
743     if ((self == NULL) || (output == NULL)) { /* input maybe is null */
744         LOGE("Invalid input parameter!");
745         return HCF_INVALID_PARAMS;
746     }
747     if (!HcfIsClassMatch((const HcfObjectBase *)self, GetAesGeneratorClass())) {
748         LOGE("Class is not match.");
749         return HCF_INVALID_PARAMS;
750     }
751     HcfResult ret = HCF_ERR_CRYPTO_OPERATION;
752     HcfCipherAesGeneratorSpiOpensslImpl *cipherImpl = (HcfCipherAesGeneratorSpiOpensslImpl *)self;
753     CipherData *data = cipherImpl->cipherData;
754     HcfAlgParaValue mode = cipherImpl->attr.mode;
755     if (data == NULL) {
756         LOGE("cipherData is null!");
757         return HCF_INVALID_PARAMS;
758     }
759 
760     if (mode == HCF_ALG_MODE_CCM) {
761         ret = CcmDoFinal(data, input, output);
762     } else if (mode == HCF_ALG_MODE_GCM) {
763         ret = GcmDoFinal(data, input, output);
764     } else { /* only ECB CBC CTR CFB OFB support */
765         ret = CommonDoFinal(data, input, output);
766     }
767 
768     FreeCipherData(&(cipherImpl->cipherData));
769     if (ret != HCF_SUCCESS) {
770         HcfBlobDataClearAndFree(output);
771     }
772     FreeRedundantOutput(output);
773     return ret;
774 }
775 
EngineAesGeneratorDestroy(HcfObjectBase * self)776 static void EngineAesGeneratorDestroy(HcfObjectBase *self)
777 {
778     if (self == NULL) {
779         return;
780     }
781     if (!HcfIsClassMatch(self, GetAesGeneratorClass())) {
782         LOGE("Class is not match.");
783         return;
784     }
785 
786     HcfCipherAesGeneratorSpiOpensslImpl *impl = (HcfCipherAesGeneratorSpiOpensslImpl *)self;
787     FreeCipherData(&(impl->cipherData));
788     HcfFree(impl);
789 }
790 
GetAesCipherSpecString(HcfCipherGeneratorSpi * self,CipherSpecItem item,char ** returnString)791 static HcfResult GetAesCipherSpecString(HcfCipherGeneratorSpi *self, CipherSpecItem item, char **returnString)
792 {
793     (void)self;
794     (void)item;
795     (void)returnString;
796     return HCF_NOT_SUPPORT;
797 }
798 
GetAesCipherSpecUint8Array(HcfCipherGeneratorSpi * self,CipherSpecItem item,HcfBlob * returnUint8Array)799 static HcfResult GetAesCipherSpecUint8Array(HcfCipherGeneratorSpi *self, CipherSpecItem item, HcfBlob *returnUint8Array)
800 {
801     (void)self;
802     (void)item;
803     (void)returnUint8Array;
804     return HCF_NOT_SUPPORT;
805 }
806 
SetAesCipherSpecUint8Array(HcfCipherGeneratorSpi * self,CipherSpecItem item,HcfBlob blob)807 static HcfResult SetAesCipherSpecUint8Array(HcfCipherGeneratorSpi *self, CipherSpecItem item, HcfBlob blob)
808 {
809     (void)self;
810     (void)item;
811     (void)blob;
812     return HCF_NOT_SUPPORT;
813 }
814 
HcfCipherAesGeneratorSpiCreate(CipherAttr * attr,HcfCipherGeneratorSpi ** generator)815 HcfResult HcfCipherAesGeneratorSpiCreate(CipherAttr *attr, HcfCipherGeneratorSpi **generator)
816 {
817     if ((attr == NULL) || (generator == NULL)) {
818         LOGE("Invalid input parameter.");
819         return HCF_INVALID_PARAMS;
820     }
821     HcfCipherAesGeneratorSpiOpensslImpl *returnImpl = (HcfCipherAesGeneratorSpiOpensslImpl *)HcfMalloc(
822         sizeof(HcfCipherAesGeneratorSpiOpensslImpl), 0);
823     if (returnImpl == NULL) {
824         LOGE("Failed to allocate returnImpl memroy!");
825         return HCF_ERR_MALLOC;
826     }
827     (void)memcpy_s(&returnImpl->attr, sizeof(CipherAttr), attr, sizeof(CipherAttr));
828     returnImpl->base.init = EngineCipherInit;
829     returnImpl->base.update = EngineUpdate;
830     returnImpl->base.doFinal = EngineDoFinal;
831     returnImpl->base.getCipherSpecString = GetAesCipherSpecString;
832     returnImpl->base.getCipherSpecUint8Array = GetAesCipherSpecUint8Array;
833     returnImpl->base.setCipherSpecUint8Array = SetAesCipherSpecUint8Array;
834     returnImpl->base.base.destroy = EngineAesGeneratorDestroy;
835     returnImpl->base.base.getClass = GetAesGeneratorClass;
836 
837     *generator = (HcfCipherGeneratorSpi *)returnImpl;
838     return HCF_SUCCESS;
839 }
840