1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include "hitls_build.h"
17 #ifdef HITLS_CRYPTO_MODES
18
19 #include "securec.h"
20 #include "bsl_sal.h"
21 #include "bsl_err_internal.h"
22 #include "crypt_errno.h"
23 #include "modes_local.h"
24 #ifdef HITLS_CRYPTO_CTR
25 #include "crypt_modes_ctr.h"
26 #endif
27 #ifdef HITLS_CRYPTO_CBC
28 #include "crypt_modes_cbc.h"
29 #endif
30 #ifdef HITLS_CRYPTO_ECB
31 #include "crypt_modes_ecb.h"
32 #endif
33 #ifdef HITLS_CRYPTO_GCM
34 #include "crypt_modes_gcm.h"
35 #endif
36 #ifdef HITLS_CRYPTO_CCM
37 #include "crypt_modes_ccm.h"
38 #endif
39 #ifdef HITLS_CRYPTO_XTS
40 #include "crypt_modes_xts.h"
41 #endif
42 #if defined(HITLS_CRYPTO_CHACHA20) && defined(HITLS_CRYPTO_CHACHA20POLY1305)
43 #include "crypt_modes_chacha20poly1305.h"
44 #endif
45 #ifdef HITLS_CRYPTO_CFB
46 #include "crypt_modes_cfb.h"
47 #endif
48 #ifdef HITLS_CRYPTO_OFB
49 #include "crypt_modes_ofb.h"
50 #endif
51 #ifdef HITLS_CRYPTO_WRAP
52 #include "crypt_modes_aes_wrap.h"
53 #endif
54
MODE_NewCtxInternal(MODES_CipherCtx * ctx,const EAL_SymMethod * method)55 int32_t MODE_NewCtxInternal(MODES_CipherCtx *ctx, const EAL_SymMethod *method)
56 {
57 ctx->commonCtx.ciphCtx = BSL_SAL_Calloc(1, method->ctxSize);
58 if (ctx->commonCtx.ciphCtx == NULL) {
59 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
60 return CRYPT_MEM_ALLOC_FAIL;
61 }
62 // block mode blockSize equal symm blockSize
63 ctx->commonCtx.blockSize = method->blockSize;
64 ctx->commonCtx.ciphMeth = method;
65 ctx->commonCtx.offset = 0;
66
67 return CRYPT_SUCCESS;
68 }
69
MODES_CipherNewCtx(int32_t algId)70 MODES_CipherCtx *MODES_CipherNewCtx(int32_t algId)
71 {
72 const EAL_SymMethod *method = EAL_GetSymMethod(algId);
73 if (method == NULL) {
74 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
75 return NULL;
76 }
77
78 MODES_CipherCtx *ctx = BSL_SAL_Calloc(1, sizeof(MODES_CipherCtx));
79 if (ctx == NULL) {
80 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
81 return ctx;
82 }
83 ctx->algId = algId;
84 int32_t ret = MODE_NewCtxInternal(ctx, method);
85 if (ret != CRYPT_SUCCESS) {
86 BSL_SAL_Free(ctx);
87 return NULL;
88 }
89 return ctx;
90 }
91
MODES_CipherInitCommonCtx(MODES_CipherCommonCtx * modeCtx,void * setSymKey,void * keyCtx,const uint8_t * key,uint32_t keyLen,const uint8_t * iv,uint32_t ivLen)92 int32_t MODES_CipherInitCommonCtx(MODES_CipherCommonCtx *modeCtx, void *setSymKey, void *keyCtx,
93 const uint8_t *key, uint32_t keyLen, const uint8_t *iv, uint32_t ivLen)
94 {
95 int32_t ret;
96 if (modeCtx->ciphMeth == NULL) {
97 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
98 return CRYPT_NULL_INPUT;
99 }
100 if (iv == NULL && ivLen > 0) {
101 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
102 return CRYPT_INVALID_ARG;
103 }
104
105 ret = ((SetKey)setSymKey)(keyCtx, key, keyLen);
106 if (ret != CRYPT_SUCCESS) {
107 BSL_ERR_PUSH_ERROR(ret);
108 return ret;
109 }
110 ret = MODES_SetIv(modeCtx, iv, ivLen);
111 if (ret != CRYPT_SUCCESS) {
112 BSL_ERR_PUSH_ERROR(ret);
113 return ret;
114 }
115 return CRYPT_SUCCESS;
116 }
117
MODES_CipherInitCtx(MODES_CipherCtx * ctx,void * setSymKey,void * keyCtx,const uint8_t * key,uint32_t keyLen,const uint8_t * iv,uint32_t ivLen,bool enc)118 int32_t MODES_CipherInitCtx(MODES_CipherCtx *ctx, void *setSymKey, void *keyCtx, const uint8_t *key, uint32_t keyLen,
119 const uint8_t *iv, uint32_t ivLen, bool enc)
120 {
121 ctx->enc = enc;
122 return MODES_CipherInitCommonCtx(&ctx->commonCtx, setSymKey, keyCtx, key, keyLen, iv, ivLen);
123 }
124
MODE_CheckUpdateParam(uint8_t blockSize,uint32_t cacheLen,uint32_t inLen,uint32_t * outLen)125 int32_t MODE_CheckUpdateParam(uint8_t blockSize, uint32_t cacheLen, uint32_t inLen, uint32_t *outLen)
126 {
127 if (inLen + cacheLen < inLen) { // Integer flipping
128 BSL_ERR_PUSH_ERROR(CRYPT_EAL_BUFF_LEN_TOO_LONG);
129 return CRYPT_EAL_BUFF_LEN_TOO_LONG;
130 }
131 if ((*outLen) < ((inLen + cacheLen) / blockSize * blockSize)) {
132 BSL_ERR_PUSH_ERROR(CRYPT_EAL_BUFF_LEN_NOT_ENOUGH);
133 return CRYPT_EAL_BUFF_LEN_NOT_ENOUGH;
134 }
135 return CRYPT_SUCCESS;
136 }
137
IfXts(CRYPT_CIPHER_AlgId id)138 static bool IfXts(CRYPT_CIPHER_AlgId id)
139 {
140 return id == CRYPT_CIPHER_AES128_XTS || id == CRYPT_CIPHER_AES256_XTS || id == CRYPT_CIPHER_SM4_XTS;
141 }
142
UnPaddingISO7816(const uint8_t * pad,uint32_t padLen,uint32_t * finLen)143 static int32_t UnPaddingISO7816(const uint8_t *pad, uint32_t padLen, uint32_t *finLen)
144 {
145 const uint8_t *p = pad;
146 uint32_t len = padLen - 1;
147 while (*(p + len) == 0 && len > 0) {
148 len--;
149 }
150 len = (*(p + len) == 0x80) ? len : padLen;
151
152 if (len == padLen) {
153 BSL_ERR_PUSH_ERROR(CRYPT_EAL_CIPHER_DATA_ERROR);
154 return CRYPT_EAL_CIPHER_DATA_ERROR;
155 }
156 (*finLen) = len;
157 return CRYPT_SUCCESS;
158 }
159
UnPaddingX923(const uint8_t * pad,uint32_t padLen,uint32_t * finLen)160 static int32_t UnPaddingX923(const uint8_t *pad, uint32_t padLen, uint32_t *finLen)
161 {
162 uint32_t len, pos, i;
163 uint32_t check = 0;
164 len = pad[padLen - 1];
165
166 check |= (uint32_t)(len > padLen);
167
168 pos = padLen - len;
169 for (i = 0; i < padLen - 1; i++) {
170 check |= (pad[i] * (uint32_t)(i >= pos));
171 }
172
173 if (check != 0) {
174 BSL_ERR_PUSH_ERROR(CRYPT_EAL_CIPHER_DATA_ERROR);
175 return CRYPT_EAL_CIPHER_DATA_ERROR;
176 }
177
178 (*finLen) = padLen - len;
179 return CRYPT_SUCCESS;
180 }
181
UnPaddingPkcs(const uint8_t * pad,uint32_t padLen,uint32_t * finLen)182 static int32_t UnPaddingPkcs(const uint8_t *pad, uint32_t padLen, uint32_t *finLen)
183 {
184 uint32_t len, pos, i;
185 uint32_t check = 0;
186
187 len = pad[padLen - 1];
188 check |= (uint32_t)((len == 0) || (len > padLen));
189
190 pos = padLen - len;
191 for (i = 0; i < padLen; i++) {
192 check |= ((pad[i] ^ len) * (uint32_t)(i >= pos));
193 }
194
195 if (check != 0) {
196 BSL_ERR_PUSH_ERROR(CRYPT_EAL_CIPHER_DATA_ERROR);
197 return CRYPT_EAL_CIPHER_DATA_ERROR;
198 }
199
200 (*finLen) = padLen - len;
201 return CRYPT_SUCCESS;
202 }
203
MODES_BlockUnPadding(int32_t padding,const uint8_t * pad,uint32_t padLen,uint32_t * dataLen)204 int32_t MODES_BlockUnPadding(int32_t padding, const uint8_t *pad, uint32_t padLen, uint32_t *dataLen)
205 {
206 int32_t ret = 0;
207 uint32_t len = *dataLen;
208 switch (padding) {
209 case CRYPT_PADDING_ISO7816:
210 ret = UnPaddingISO7816(pad, padLen, &len);
211 break;
212 case CRYPT_PADDING_X923:
213 ret = UnPaddingX923(pad, padLen, &len);
214 break;
215 case CRYPT_PADDING_PKCS5:
216 case CRYPT_PADDING_PKCS7:
217 ret = UnPaddingPkcs(pad, padLen, &len);
218 break;
219 default:
220 break;
221 }
222
223 *dataLen = len;
224 return ret;
225 }
226
MODES_BlockPadding(int32_t algId,int32_t padding,uint8_t blockSize,uint8_t * data,uint8_t * dataLen)227 int32_t MODES_BlockPadding(int32_t algId, int32_t padding, uint8_t blockSize, uint8_t *data, uint8_t *dataLen)
228 {
229 uint8_t tempLen = *dataLen;
230 uint8_t *pad = data + tempLen;
231 uint8_t padLen = blockSize - tempLen;
232 uint8_t i;
233 *dataLen += padLen;
234 switch (padding) {
235 case CRYPT_PADDING_NONE:
236 *dataLen = tempLen;
237 if (tempLen % blockSize != 0) {
238 return IfXts(algId) ? CRYPT_SUCCESS : CRYPT_MODE_ERR_INPUT_LEN;
239 }
240 break;
241 case CRYPT_PADDING_ZEROS:
242 for (i = 0; i < padLen; i++) {
243 pad[i] = 0x00L;
244 }
245 break;
246 case CRYPT_PADDING_ISO7816:
247 pad[0] = 0x80;
248 for (i = 1; i < padLen; i++) {
249 pad[i] = 0x00L;
250 }
251 break;
252 case CRYPT_PADDING_X923:
253 for (i = 0; i < padLen - 1; i++) {
254 pad[i] = 0x00L;
255 }
256 pad[padLen - 1] = padLen;
257 break;
258 case CRYPT_PADDING_PKCS5:
259 case CRYPT_PADDING_PKCS7:
260 for (i = 0; i < padLen; i++) {
261 pad[i] = padLen;
262 }
263 break;
264 default:
265 *dataLen = tempLen;
266 return CRYPT_INVALID_ARG;
267 }
268 return CRYPT_SUCCESS;
269 }
270
MODES_CipherUpdateCache(MODES_CipherCtx * ctx,void * blockUpdate,const uint8_t ** in,uint32_t * inLen,uint8_t ** out,uint32_t * outLen)271 int32_t MODES_CipherUpdateCache(MODES_CipherCtx *ctx, void *blockUpdate, const uint8_t **in, uint32_t *inLen,
272 uint8_t **out, uint32_t *outLen)
273 {
274 int32_t ret;
275 uint8_t blockSize = ctx->commonCtx.blockSize;
276 // Process the cache. If there is cached data, the cache data is padded into a block first.
277 if (ctx->dataLen > 0) {
278 uint8_t padding = blockSize - ctx->dataLen;
279 padding = (*inLen) > (padding) ? padding : (uint8_t)(*inLen);
280 if (padding != 0) {
281 (void)memcpy_s(ctx->data + ctx->dataLen, (EAL_MAX_BLOCK_LENGTH - ctx->dataLen), (*in), padding);
282 (*inLen) -= padding;
283 (*in) += padding;
284 ctx->dataLen += padding;
285 }
286 }
287 // No block is formed, return.
288 if (ctx->dataLen != blockSize) {
289 return CRYPT_SUCCESS;
290 }
291
292 // If the block is padded, perform operations on this block first.
293 if (ctx->enc) {
294 ret = ((EncryptBlock)blockUpdate)(&ctx->commonCtx, ctx->data, *out, blockSize);
295 } else {
296 // If it's decryption and the cached data + input data is equal to blockSize,
297 // may be it's the last piece of data with padding, the data is cached in the ctx and left for final processing.
298 if ((*inLen) == 0 && (ctx->pad != CRYPT_PADDING_NONE)) {
299 (*outLen) = 0;
300 return CRYPT_SUCCESS;
301 }
302 ret = ((DecryptBlock)blockUpdate)(&ctx->commonCtx, ctx->data, *out, blockSize);
303 }
304
305 if (ret != CRYPT_SUCCESS) {
306 BSL_ERR_PUSH_ERROR(ret);
307 return ret;
308 }
309 ctx->dataLen = 0;
310 (*outLen) = blockSize;
311 (*out) += blockSize;
312
313 return CRYPT_SUCCESS;
314 }
315
MODES_CipherFinal(MODES_CipherCtx * modeCtx,void * blockUpdate,uint8_t * out,uint32_t * outLen)316 int32_t MODES_CipherFinal(MODES_CipherCtx *modeCtx, void *blockUpdate, uint8_t *out, uint32_t *outLen)
317 {
318 int32_t ret;
319 uint32_t outLenTemp;
320 if (out == NULL || outLen == NULL) {
321 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
322 return CRYPT_NULL_INPUT;
323 }
324 if (modeCtx->pad != CRYPT_PADDING_NONE && (*outLen) < modeCtx->commonCtx.blockSize) {
325 BSL_ERR_PUSH_ERROR(CRYPT_EAL_BUFF_LEN_NOT_ENOUGH);
326 return CRYPT_EAL_BUFF_LEN_NOT_ENOUGH;
327 }
328
329 if (modeCtx->enc) {
330 ret = MODES_BlockPadding(modeCtx->algId, modeCtx->pad,
331 modeCtx->commonCtx.blockSize, modeCtx->data, &modeCtx->dataLen);
332 if (ret != CRYPT_SUCCESS) {
333 BSL_ERR_PUSH_ERROR(ret);
334 return ret;
335 }
336 if (modeCtx->dataLen == 0) {
337 *outLen = modeCtx->dataLen;
338 return CRYPT_SUCCESS;
339 }
340 ret = ((EncryptBlock)blockUpdate)(&modeCtx->commonCtx, modeCtx->data, out, modeCtx->dataLen);
341 if (ret != CRYPT_SUCCESS) {
342 BSL_ERR_PUSH_ERROR(ret);
343 return ret;
344 }
345 *outLen = modeCtx->dataLen;
346 } else {
347 if (modeCtx->dataLen == 0) {
348 *outLen = modeCtx->dataLen;
349 return CRYPT_SUCCESS;
350 }
351
352 ret = ((DecryptBlock)blockUpdate)(&modeCtx->commonCtx, modeCtx->data, out, modeCtx->dataLen);
353 if (ret != CRYPT_SUCCESS) {
354 BSL_ERR_PUSH_ERROR(ret);
355 return ret;
356 }
357 outLenTemp = modeCtx->dataLen;
358 ret = MODES_BlockUnPadding(modeCtx->pad, out, modeCtx->commonCtx.blockSize, &outLenTemp);
359 if (ret != CRYPT_SUCCESS) {
360 BSL_ERR_PUSH_ERROR(ret);
361 return ret;
362 }
363 *outLen = outLenTemp;
364 }
365 modeCtx->dataLen = 0;
366 return ret;
367 }
368
MODES_CipherUpdate(MODES_CipherCtx * modeCtx,void * blockUpdate,const uint8_t * in,uint32_t inLen,uint8_t * out,uint32_t * outLen)369 int32_t MODES_CipherUpdate(MODES_CipherCtx *modeCtx, void *blockUpdate, const uint8_t *in, uint32_t inLen,
370 uint8_t *out, uint32_t *outLen)
371 {
372 int32_t ret;
373 uint32_t tmpLen = inLen;
374 const uint8_t *tmpIn = in;
375 uint8_t *tmpOut = (uint8_t *)out;
376
377 ret = MODE_CheckUpdateParam(modeCtx->commonCtx.blockSize, modeCtx->dataLen, inLen, outLen);
378 if (ret != CRYPT_SUCCESS) {
379 BSL_ERR_PUSH_ERROR(ret);
380 return ret;
381 }
382 *outLen = 0;
383 ret = MODES_CipherUpdateCache(modeCtx, blockUpdate, &tmpIn, &tmpLen, &tmpOut, outLen);
384 if (ret != CRYPT_SUCCESS) {
385 BSL_ERR_PUSH_ERROR(ret);
386 return ret;
387 }
388 if (tmpLen == 0) {
389 return CRYPT_SUCCESS;
390 }
391
392 uint8_t left = tmpLen % modeCtx->commonCtx.blockSize;
393 uint32_t len = tmpLen - left;
394 if (len > 0) {
395 if (modeCtx->enc) {
396 ret = ((EncryptBlock)blockUpdate)(&modeCtx->commonCtx, tmpIn, tmpOut, len);
397 } else {
398 // If it's decryption and the cached data + input data is equal to blockSize,
399 // may be it's the last piece of data with padding, the data is cached in the ctx and left for final processing.
400 if ((modeCtx->pad != CRYPT_PADDING_NONE) && left == 0) {
401 left = modeCtx->commonCtx.blockSize;
402 len -= modeCtx->commonCtx.blockSize;
403 }
404 if (len > 0) {
405 ret = ((DecryptBlock)blockUpdate)(&modeCtx->commonCtx, tmpIn, tmpOut, len);
406 }
407 }
408 if (ret != CRYPT_SUCCESS) {
409 BSL_ERR_PUSH_ERROR(ret);
410 return ret;
411 }
412 }
413 // Process the new cache.
414 if (left > 0) {
415 (void)memcpy_s(modeCtx->data, modeCtx->commonCtx.blockSize, tmpIn + len, left);
416 modeCtx->dataLen = left;
417 }
418
419 // The encryption/decryption is successful. OutLen is updated.
420 (*outLen) += len;
421 return CRYPT_SUCCESS;
422 }
423
MODES_Clean(MODES_CipherCommonCtx * ctx)424 void MODES_Clean(MODES_CipherCommonCtx *ctx)
425 {
426 if (ctx == NULL) {
427 return;
428 }
429 BSL_SAL_CleanseData((void *)(ctx->buf), MODES_MAX_BUF_LENGTH);
430 BSL_SAL_CleanseData((void *)(ctx->iv), MODES_MAX_IV_LENGTH);
431 ctx->ciphMeth->cipherDeInitCtx(ctx->ciphCtx);
432 ctx->offset = 0;
433 ctx->ivIndex = 0;
434 }
435
MODES_CipherDeInitCtx(MODES_CipherCtx * modeCtx)436 int32_t MODES_CipherDeInitCtx(MODES_CipherCtx *modeCtx)
437 {
438 if (modeCtx == NULL) {
439 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
440 return CRYPT_NULL_INPUT;
441 }
442 (void)memset_s(modeCtx->data, EAL_MAX_BLOCK_LENGTH, 0, EAL_MAX_BLOCK_LENGTH);
443 modeCtx->dataLen = 0;
444 modeCtx->pad = CRYPT_PADDING_NONE;
445 MODES_Clean(&modeCtx->commonCtx);
446 return CRYPT_SUCCESS;
447 }
448
MODES_CipherFreeCtx(MODES_CipherCtx * modeCtx)449 void MODES_CipherFreeCtx(MODES_CipherCtx *modeCtx)
450 {
451 if (modeCtx == NULL) {
452 return;
453 }
454 (void)MODES_CipherDeInitCtx(modeCtx);
455 BSL_SAL_FREE(modeCtx->commonCtx.ciphCtx);
456 BSL_SAL_Free(modeCtx);
457 }
458
459
MODES_SetIv(MODES_CipherCommonCtx * ctx,const uint8_t * val,uint32_t len)460 int32_t MODES_SetIv(MODES_CipherCommonCtx *ctx, const uint8_t *val, uint32_t len)
461 {
462 if (val == NULL) {
463 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
464 return CRYPT_NULL_INPUT;
465 }
466
467 if (len != ctx->blockSize) {
468 BSL_ERR_PUSH_ERROR(CRYPT_MODES_IVLEN_ERROR);
469 return CRYPT_MODES_IVLEN_ERROR;
470 }
471
472 if (memcpy_s(ctx->iv, MODES_MAX_IV_LENGTH, val, len) != EOK) {
473 BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL);
474 return CRYPT_SECUREC_FAIL;
475 }
476 ctx->offset = 0; // If the IV value is changed, the original offset is useless.
477 ctx->ivIndex = 0;
478 return CRYPT_SUCCESS;
479 }
480
MODES_GetIv(MODES_CipherCommonCtx * ctx,uint8_t * val,uint32_t len)481 int32_t MODES_GetIv(MODES_CipherCommonCtx *ctx, uint8_t *val, uint32_t len)
482 {
483 if (val == NULL) {
484 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
485 return CRYPT_NULL_INPUT;
486 }
487
488 uint32_t ivLen = ctx->blockSize;
489
490 if (len != ivLen) {
491 BSL_ERR_PUSH_ERROR(CRYPT_MODE_ERR_INPUT_LEN);
492 return CRYPT_MODE_ERR_INPUT_LEN;
493 }
494
495 (void)memcpy_s(val, len, ctx->iv, ivLen);
496
497 return CRYPT_SUCCESS;
498 }
499
MODES_CipherCtrl(MODES_CipherCtx * ctx,int32_t opt,void * val,uint32_t len)500 int32_t MODES_CipherCtrl(MODES_CipherCtx *ctx, int32_t opt, void *val, uint32_t len)
501 {
502 switch (opt) {
503 case CRYPT_CTRL_REINIT_STATUS:
504 (void)memset_s(ctx->data, EAL_MAX_BLOCK_LENGTH, 0, EAL_MAX_BLOCK_LENGTH);
505 ctx->dataLen = 0;
506 ctx->pad = CRYPT_PADDING_NONE;
507 return MODES_SetIv(&ctx->commonCtx, val, len);
508 case CRYPT_CTRL_GET_IV:
509 return MODES_GetIv(&ctx->commonCtx, (uint8_t *)val, len);
510 default:
511 if (ctx->commonCtx.ciphMeth == NULL ||
512 ctx->commonCtx.ciphMeth->cipherCtrl == NULL) {
513 BSL_ERR_PUSH_ERROR(CRYPT_MODES_CTRL_TYPE_ERROR);
514 return CRYPT_MODES_CTRL_TYPE_ERROR;
515 }
516 return ctx->commonCtx.ciphMeth->cipherCtrl(ctx->commonCtx.ciphCtx, opt, val, len);
517 }
518 }
519
MODES_CipherStreamProcess(void * processFuncs,void * ctx,const uint8_t * in,uint32_t inLen,uint8_t * out,uint32_t * outLen)520 int32_t MODES_CipherStreamProcess(void *processFuncs, void *ctx, const uint8_t *in, uint32_t inLen,
521 uint8_t *out, uint32_t *outLen)
522 {
523 int32_t ret;
524 if (inLen == 0) {
525 *outLen = 0;
526 return CRYPT_SUCCESS;
527 }
528 if (inLen > *outLen) {
529 BSL_ERR_PUSH_ERROR(CRYPT_MODE_BUFF_LEN_NOT_ENOUGH);
530 return CRYPT_MODE_BUFF_LEN_NOT_ENOUGH;
531 }
532
533 ret = ((CipherStreamProcess)(processFuncs))(ctx, in, out, inLen);
534 if (ret != CRYPT_SUCCESS) {
535 BSL_ERR_PUSH_ERROR(ret);
536 return ret;
537 }
538 *outLen = inLen;
539 return CRYPT_SUCCESS;
540 }
541
542 // Note that CRYPT_PADDING_ZEROS cannot restore the plaintext length.
543 // If uses it, need to maintain the length themselves
MODES_SetPaddingCheck(int32_t pad)544 int32_t MODES_SetPaddingCheck(int32_t pad)
545 {
546 if (pad >= CRYPT_PADDING_MAX_COUNT || pad < CRYPT_PADDING_NONE) {
547 BSL_ERR_PUSH_ERROR(CRYPT_MODES_PADDING_NOT_SUPPORT);
548 return CRYPT_MODES_PADDING_NOT_SUPPORT;
549 }
550 return CRYPT_SUCCESS;
551 }
552
MODES_SetEncryptKey(MODES_CipherCommonCtx * ctx,const uint8_t * key,uint32_t len)553 int32_t MODES_SetEncryptKey(MODES_CipherCommonCtx *ctx, const uint8_t *key, uint32_t len)
554 {
555 // The ctx and key have been checked at the EAL layer and will not be checked again here.
556 // The keyMethod will support registration in the future. Therefore, this check is added.
557 if (ctx == NULL || ctx->ciphMeth == NULL) {
558 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
559 return CRYPT_NULL_INPUT;
560 }
561 return ctx->ciphMeth->setEncryptKey(ctx->ciphCtx, key, len);
562 }
563
MODES_SetDecryptKey(MODES_CipherCommonCtx * ctx,const uint8_t * key,uint32_t len)564 int32_t MODES_SetDecryptKey(MODES_CipherCommonCtx *ctx, const uint8_t *key, uint32_t len)
565 {
566 // The ctx and key have been checked at the EAL layer and will not be checked again here.
567 // The keyMethod will support registration in the future. Therefore, this check is added.
568 if (ctx == NULL || ctx->ciphMeth == NULL) {
569 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
570 return CRYPT_NULL_INPUT;
571 }
572 return ctx->ciphMeth->setDecryptKey(ctx->ciphCtx, key, len);
573 }
574
575 #endif // HITLS_CRYPTO_MODES
576