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