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