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