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