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