• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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