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