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