• 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_CFB
18 
19 #include <stdbool.h>
20 #include "securec.h"
21 #include "bsl_err_internal.h"
22 #include "bsl_sal.h"
23 #include "crypt_modes_cfb.h"
24 #include "modes_local.h"
25 #include "crypt_errno.h"
26 #include "crypt_local_types.h"
27 #include "crypt_modes.h"
28 
29 /* 8-bit | 64-bit | 128-bit CFB encryption. Here, len indicates the number of bytes to be processed. */
MODES_CFB_BytesEncrypt(MODES_CipherCFBCtx * ctx,const uint8_t * in,uint8_t * out,uint32_t len)30 static int32_t MODES_CFB_BytesEncrypt(MODES_CipherCFBCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
31 {
32     const uint8_t *input = in;
33     uint8_t *output = out;
34     uint8_t *tmp = ctx->modeCtx.buf;
35     uint32_t blockSize = ctx->modeCtx.blockSize;
36     uint32_t feedbackBytes = ctx->feedbackBits >> 3;    // right shifting by 3 to obtain the number of bytes.
37     uint32_t left = len;
38     uint32_t i, k;
39 
40     // If the remaining encryption iv is not used up last time, use that part to perform XOR.
41     while (left > 0 && ctx->modeCtx.offset > 0) {
42         ctx->modeCtx.iv[ctx->modeCtx.offset] ^= *(input++);
43         *(output++) = ctx->modeCtx.iv[ctx->modeCtx.offset];
44         left--;
45         ctx->modeCtx.offset = (ctx->modeCtx.offset + 1) % blockSize;
46     }
47 
48     while (left > 0) {
49         // Encrypt the IV.
50         int32_t ret = ctx->modeCtx.ciphMeth->encryptBlock(ctx->modeCtx.ciphCtx, ctx->modeCtx.iv, tmp, blockSize);
51         if (ret != CRYPT_SUCCESS) {
52             BSL_ERR_PUSH_ERROR(ret);
53             return ret;
54         }
55 
56         i = 0;
57 
58         // The first (blockSize - feedbackBytes) bytes are filled with the least significant bytes of the previous IV.
59         if (blockSize - feedbackBytes > 0) {
60             (void)memmove_s(&ctx->modeCtx.iv[0], blockSize, &ctx->modeCtx.iv[feedbackBytes],
61                 blockSize - feedbackBytes);
62             i = blockSize - feedbackBytes;
63         }
64 
65         // The input data is XORed with the encrypted IV, and the current ciphertext is sent to the next IV.
66         if (left >= feedbackBytes) {
67             // Enter the last feedbackBytes in ciphertext.
68             for (k = 0; i < blockSize; i++, k++) {
69                 output[k] = input[k] ^ tmp[k];
70                 ctx->modeCtx.iv[i] = output[k];
71             }
72             UPDATE_VALUES(left, input, output, feedbackBytes);
73         } else {
74             // Enter the last feedbackBytes in ciphertext.
75             // The cache with insufficient feedbackBytes is used to encrypt the IV.
76             for (k = 0; k < left; k++) {
77                 output[k] = input[k] ^ tmp[k];
78                 ctx->modeCtx.iv[i++] = output[k];
79             }
80 
81             while (i < blockSize) {
82                 ctx->modeCtx.iv[i++] = tmp[k++];
83             }
84             ctx->modeCtx.offset = (uint8_t)(blockSize - feedbackBytes + left);
85             left = 0;
86         }
87     }
88 
89     return CRYPT_SUCCESS;
90 }
91 
MODES_CFB128_BytesEncrypt(MODES_CipherCFBCtx * ctx,const uint8_t * in,uint8_t * out,uint32_t len)92 static int32_t MODES_CFB128_BytesEncrypt(MODES_CipherCFBCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
93 {
94     const uint8_t *inp = in;
95     uint8_t *outp = out;
96     uint32_t blockSize = ctx->modeCtx.blockSize;
97     uint8_t *iv = ctx->modeCtx.iv;
98     uint32_t left = len;
99     int32_t ret;
100     while (left > 0 && ctx->modeCtx.offset > 0) {
101         iv[ctx->modeCtx.offset] ^= *(inp++);
102         *(outp++) = iv[ctx->modeCtx.offset];
103         left--;
104         ctx->modeCtx.offset = (ctx->modeCtx.offset + 1) % blockSize;
105     }
106     while (left >= blockSize) {
107         ret = ctx->modeCtx.ciphMeth->encryptBlock(ctx->modeCtx.ciphCtx, iv, iv, blockSize);
108         if (ret != CRYPT_SUCCESS) {
109             BSL_ERR_PUSH_ERROR(ret);
110             return ret;
111         }
112 #ifdef FORCE_ADDR_ALIGN
113         for (uint32_t i = 0; i < blockSize; i++) {
114             iv[i] ^= inp[i];
115             out[i] = iv[i];
116         }
117 #else
118         for (uint32_t i = 0; i < blockSize; i += sizeof(uint64_t)) {
119             *((uint64_t *)(iv + i)) ^= *((const uint64_t *)(inp + i));
120             *((uint64_t *)(outp + i)) = *((uint64_t *)(iv + i));
121         }
122 #endif
123         UPDATE_VALUES(left, inp, outp, blockSize);
124     }
125     if (left > 0) {
126         ret = ctx->modeCtx.ciphMeth->encryptBlock(ctx->modeCtx.ciphCtx, iv, iv, blockSize);
127         if (ret != CRYPT_SUCCESS) {
128             BSL_ERR_PUSH_ERROR(ret);
129             return ret;
130         }
131         uint32_t i = 0;
132         for (; i < left; i++) {
133             iv[i] ^= inp[i];
134             outp[i] = iv[i];
135         }
136         ctx->modeCtx.offset = (uint8_t)left;
137     }
138 
139     return CRYPT_SUCCESS;
140 }
141 
142 /* 8-bit | 64-bit | 128-bit CFB decryption. Here, len indicates the number of bytes to be processed. */
MODES_CFB_BytesDecrypt(MODES_CipherCFBCtx * ctx,const uint8_t * in,uint8_t * out,uint32_t len)143 static int32_t MODES_CFB_BytesDecrypt(MODES_CipherCFBCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
144 {
145     const uint8_t *input = in;
146     uint8_t *output = out;
147     uint8_t *tmp = ctx->modeCtx.buf;
148     uint32_t blockSize = ctx->modeCtx.blockSize;
149     uint32_t feedbackBytes = ctx->feedbackBits >> 3;
150     uint32_t left = len;
151     uint32_t i, k;
152 
153     // If the remaining encryption iv is not used up last time, use that part to perform XOR.
154     while (left > 0 && ctx->modeCtx.offset > 0) {
155         uint8_t tmpInput = *input;      // To support the same address in and out
156         *(output++) = ctx->modeCtx.iv[ctx->modeCtx.offset] ^ *(input++);
157         ctx->modeCtx.iv[ctx->modeCtx.offset] = tmpInput;
158         left--;
159         ctx->modeCtx.offset = (ctx->modeCtx.offset + 1) % blockSize;
160     }
161 
162     while (left > 0) {
163         // Encrypt the IV.
164         int32_t ret = ctx->modeCtx.ciphMeth->encryptBlock(ctx->modeCtx.ciphCtx, ctx->modeCtx.iv, tmp, blockSize);
165         if (ret != CRYPT_SUCCESS) {
166             BSL_ERR_PUSH_ERROR(ret);
167             return ret;
168         }
169 
170         i = 0;
171 
172         // The first (blockSize - feedbackBytes) bytes are filled with the least significant bytes of the previous IV.
173         if (blockSize - feedbackBytes > 0) {
174             (void)memmove_s(&ctx->modeCtx.iv[0], blockSize, &ctx->modeCtx.iv[feedbackBytes],
175                 blockSize - feedbackBytes);
176             i = blockSize - feedbackBytes;
177         }
178 
179         // The input data is XORed with the encrypted IV, and the current ciphertext is sent to the next IV.
180         if (left >= feedbackBytes) {
181             // Enter the last feedbackBytes in ciphertext.
182             for (k = 0; i < blockSize; i++, k++) {
183                 ctx->modeCtx.iv[i] = input[k];
184                 output[k] = input[k] ^ tmp[k];
185             }
186             UPDATE_VALUES(left, input, output, feedbackBytes);
187         } else {
188             // Enter the last feedbackBytes in ciphertext.
189             // The cache with insufficient feedbackBytes is used to encrypt the IV.
190             for (k = 0; k < left; k++) {
191                 ctx->modeCtx.iv[i++] = input[k];
192                 output[k] = input[k] ^ tmp[k];
193             }
194 
195             while (i < blockSize) {
196                 ctx->modeCtx.iv[i++] = tmp[k++];
197             }
198             ctx->modeCtx.offset = (uint8_t)(blockSize - feedbackBytes + left);
199             left = 0;
200         }
201     }
202 
203     return CRYPT_SUCCESS;
204 }
205 
MODES_CFB128_BytesDecrypt(MODES_CipherCFBCtx * ctx,const uint8_t * in,uint8_t * out,uint32_t len)206 static int32_t MODES_CFB128_BytesDecrypt(MODES_CipherCFBCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
207 {
208     const uint8_t *inp = in;
209     uint8_t *outp = out;
210     uint8_t *iv = ctx->modeCtx.iv;
211     uint32_t blockSize = ctx->modeCtx.blockSize;
212     uint32_t left = len;
213     int32_t ret;
214     while (left > 0 && ctx->modeCtx.offset > 0) {
215         uint8_t tmpInput = *inp;      // To support the same address in and out
216         *(outp++) = iv[ctx->modeCtx.offset] ^ *(inp++);
217         iv[ctx->modeCtx.offset] = tmpInput;
218         left--;
219         ctx->modeCtx.offset = (ctx->modeCtx.offset + 1) % blockSize;
220     }
221     while (left >= blockSize) {
222         ret = ctx->modeCtx.ciphMeth->encryptBlock(ctx->modeCtx.ciphCtx, iv, iv, blockSize);
223         if (ret != CRYPT_SUCCESS) {
224             BSL_ERR_PUSH_ERROR(ret);
225             return ret;
226         }
227 #ifdef FORCE_ADDR_ALIGN
228         for (uint32_t i = 0; i < blockSize; i++) {
229             uint8_t c = inp[i];
230             outp[i] = iv[i] ^ c;
231             iv[i] = c;
232         }
233 #else
234         for (uint32_t i = 0; i < blockSize; i += sizeof(uint64_t)) {
235             uint64_t ti = *((const uint64_t *)(inp + i));
236             *((uint64_t *)(outp + i)) = *((uint64_t *)(iv + i)) ^ ti;
237             *((uint64_t *)(iv + i)) = ti;
238         }
239 #endif
240         UPDATE_VALUES(left, inp, outp, blockSize);
241     }
242     if (left > 0) {
243         ret = ctx->modeCtx.ciphMeth->encryptBlock(ctx->modeCtx.ciphCtx, iv, iv, blockSize);
244         if (ret != CRYPT_SUCCESS) {
245             BSL_ERR_PUSH_ERROR(ret);
246             return ret;
247         }
248         uint32_t i = 0;
249         for (; i < left; i++) {
250             uint8_t b = inp[i];
251             outp[i] = iv[i] ^ b;
252             iv[i] = b;
253         }
254         ctx->modeCtx.offset = (uint8_t)left;
255     }
256     return CRYPT_SUCCESS;
257 }
258 
Cfb1Crypt(MODES_CipherCFBCtx * ctx,const uint8_t * in,uint8_t * out,bool enc)259 static int32_t Cfb1Crypt(MODES_CipherCFBCtx *ctx, const uint8_t *in, uint8_t *out, bool enc)
260 {
261     int32_t ret;
262     uint8_t *tmp = ctx->modeCtx.buf;
263     uint32_t blockSize = ctx->modeCtx.blockSize;
264     uint32_t i;
265 
266     // Encrypt the IV.
267     ret = ctx->modeCtx.ciphMeth->encryptBlock(ctx->modeCtx.ciphCtx, ctx->modeCtx.iv, tmp, blockSize);
268     if (ret != CRYPT_SUCCESS) {
269         BSL_ERR_PUSH_ERROR(ret);
270         return ret;
271     }
272 
273     for (i = 0; i < blockSize - 1; i++) {
274         // All bytes are shifted left by one bit,
275         // and the least significant bits are obtained by shifting right by 7 bits from the next byte.
276         ctx->modeCtx.iv[i] = (ctx->modeCtx.iv[i] << 1) | (ctx->modeCtx.iv[i + 1] >> 7);
277     }
278 
279     if (enc) {
280         *out = tmp[0] ^ *in;
281         // The last byte is shifted to the left by one bit and then filled in the ciphertext.
282         // Shifted to the right by 7 bits to obtain the first bit of the byte.
283         ctx->modeCtx.iv[i] = (ctx->modeCtx.iv[i] << 1) | (*out >> 7);
284     } else {
285         // The last byte is shifted to the left by one bit and then filled in the ciphertext.
286         // Shifted to the right by 7 bits to obtain the first bit of the byte.
287         ctx->modeCtx.iv[i] = (ctx->modeCtx.iv[i] << 1) | (*in >> 7);
288         *out = tmp[0] ^ *in;
289     }
290 
291     return CRYPT_SUCCESS;
292 }
293 
294 /* 1-bit CFB. Here, len indicates the number of bits to be processed. */
MODES_CFB_BitCrypt(MODES_CipherCFBCtx * ctx,const uint8_t * in,uint8_t * out,uint32_t len,bool enc)295 int32_t MODES_CFB_BitCrypt(MODES_CipherCFBCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc)
296 {
297     int32_t ret;
298     uint8_t tmp[2];
299     uint32_t pos;
300     for (uint32_t i = 0; i < len; i++) {
301         // 7 - i % 8 is used to obtain the number of bits in the byte stream (high bit -> low bit).
302         pos = 7 - i % 8;
303         // Obtain the bits to be encrypted. 0x80 indicates a byte whose most significant bit is 1.
304         tmp[0] = ((in[i / 8] & (1 << pos)) > 0) ? 0x80 : 0;
305         ret = Cfb1Crypt(ctx, &tmp[0], &tmp[1], enc);
306         if (ret != CRYPT_SUCCESS) {
307             BSL_ERR_PUSH_ERROR(ret);
308             return ret;
309         }
310         // Divide by 8 to obtain the current byte position. Assign the out encryption bit to 0.
311         out[i / 8] = out[i / 8] & ~(1u << pos);
312         // Divide by 8 to obtain the current byte position. tmpOut[0] >> 7 to obtain the most significant bit.
313         out[i / 8] |= (tmp[1] >> 7) << pos; // Assign the out encryption bit to the encrypted/decrypted value.
314     }
315     (void)memset_s(tmp, sizeof(tmp), 0, sizeof(tmp));
316     return CRYPT_SUCCESS;
317 }
318 
MODES_CFB_Encrypt(MODES_CipherCFBCtx * ctx,const uint8_t * in,uint8_t * out,uint32_t len)319 int32_t MODES_CFB_Encrypt(MODES_CipherCFBCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
320 {
321     if (ctx == NULL || in == NULL || out == NULL || len == 0) {
322         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
323         return CRYPT_NULL_INPUT;
324     }
325 
326     switch (ctx->feedbackBits) {
327         case 1:
328             return MODES_CFB_BitCrypt(ctx, in, out, len * 8, true); // Each byte occupies 8 bits.
329         case 8:
330         case 64:
331             return MODES_CFB_BytesEncrypt(ctx, in, out, len);
332         case 128:
333             return MODES_CFB128_BytesEncrypt(ctx, in, out, len);
334         default:
335             BSL_ERR_PUSH_ERROR(CRYPT_MODES_ERR_FEEDBACKSIZE);
336             return CRYPT_MODES_ERR_FEEDBACKSIZE;
337     }
338 }
339 
MODES_CFB_Decrypt(MODES_CipherCFBCtx * ctx,const uint8_t * in,uint8_t * out,uint32_t len)340 int32_t MODES_CFB_Decrypt(MODES_CipherCFBCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
341 {
342     if (ctx == NULL || in == NULL || out == NULL || len == 0) {
343         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
344         return CRYPT_NULL_INPUT;
345     }
346     switch (ctx->feedbackBits) {
347         case 1:     // 1-bit cfb. Convert the length of bytes to the length of bits.
348             return MODES_CFB_BitCrypt(ctx, in, out, len * 8, false); // Each byte occupies 8 bits.
349         case 8:     // 8-bit cfb
350         case 64:    // 64-bit cfb
351             return MODES_CFB_BytesDecrypt(ctx, in, out, len);
352         case 128:   // 128-bit cfb
353             return MODES_CFB128_BytesDecrypt(ctx, in, out, len);
354         default:
355             BSL_ERR_PUSH_ERROR(CRYPT_MODES_ERR_FEEDBACKSIZE);
356             return CRYPT_MODES_ERR_FEEDBACKSIZE;
357     }
358 }
359 
SetFeedbackSize(MODES_CipherCFBCtx * ctx,const uint32_t * val,uint32_t len)360 static int32_t SetFeedbackSize(MODES_CipherCFBCtx *ctx, const uint32_t *val, uint32_t len)
361 {
362     if (val == NULL) {
363         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
364         return CRYPT_NULL_INPUT;
365     }
366     if (len != sizeof(uint32_t)) {
367         BSL_ERR_PUSH_ERROR(CRYPT_MODE_ERR_INPUT_LEN);
368         return CRYPT_MODE_ERR_INPUT_LEN;
369     }
370     if (*val != 1 && *val != 8 && *val != 64 && *val != 128) { // set 1|8|64|128 feedbackbits only
371         BSL_ERR_PUSH_ERROR(CRYPT_MODES_ERR_FEEDBACKSIZE);
372         return CRYPT_MODES_ERR_FEEDBACKSIZE;
373     }
374 
375     if (*val > (uint32_t)(ctx->modeCtx.blockSize * 8)) {
376         BSL_ERR_PUSH_ERROR(CRYPT_MODES_ERR_FEEDBACKSIZE);
377         return CRYPT_MODES_ERR_FEEDBACKSIZE;
378     }
379     ctx->feedbackBits = (uint8_t)*val;
380     return CRYPT_SUCCESS;
381 }
382 
GetFeedbackSize(MODES_CipherCFBCtx * ctx,uint32_t * val,uint32_t len)383 static int32_t GetFeedbackSize(MODES_CipherCFBCtx *ctx, uint32_t *val, uint32_t len)
384 {
385     if (val == NULL) {
386         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
387         return CRYPT_NULL_INPUT;
388     }
389     if (len != sizeof(uint32_t)) {
390         BSL_ERR_PUSH_ERROR(CRYPT_MODE_ERR_INPUT_LEN);
391         return CRYPT_MODE_ERR_INPUT_LEN;
392     }
393     *val = ctx->feedbackBits;
394     return CRYPT_SUCCESS;
395 }
396 
MODES_CFB_Ctrl(MODES_CFB_Ctx * modeCtx,int32_t opt,void * val,uint32_t len)397 int32_t MODES_CFB_Ctrl(MODES_CFB_Ctx *modeCtx, int32_t opt, void *val, uint32_t len)
398 {
399     if (modeCtx == NULL) {
400         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
401         return CRYPT_NULL_INPUT;
402     }
403 
404     switch (opt) {
405         case CRYPT_CTRL_REINIT_STATUS:
406             modeCtx->cfbCtx.cacheIndex = 0;
407             return MODES_SetIv(&modeCtx->cfbCtx.modeCtx, val, len);
408         case CRYPT_CTRL_GET_IV:
409             return MODES_GetIv(&modeCtx->cfbCtx.modeCtx, (uint8_t *)val, len);
410         case CRYPT_CTRL_SET_FEEDBACKSIZE:
411             return SetFeedbackSize(&modeCtx->cfbCtx, (uint32_t *)val, len);
412         case CRYPT_CTRL_GET_FEEDBACKSIZE:
413             return GetFeedbackSize(&modeCtx->cfbCtx, (uint32_t *)val, len);
414         case CRYPT_CTRL_GET_BLOCKSIZE:
415             if (val == NULL || len != sizeof(uint32_t)) {
416                 return CRYPT_INVALID_ARG;
417             }
418             *(int32_t *)val = 1;
419             return CRYPT_SUCCESS;
420         default:
421             if (modeCtx->cfbCtx.modeCtx.ciphMeth == NULL ||
422                 modeCtx->cfbCtx.modeCtx.ciphMeth->cipherCtrl == NULL) {
423                 BSL_ERR_PUSH_ERROR(CRYPT_MODES_CTRL_TYPE_ERROR);
424                 return CRYPT_MODES_CTRL_TYPE_ERROR;
425             }
426             return modeCtx->cfbCtx.modeCtx.ciphMeth->cipherCtrl(modeCtx->cfbCtx.modeCtx.ciphCtx, opt, val, len);
427     }
428 }
429 
MODES_CFB_NewCtx(int32_t algId)430 MODES_CFB_Ctx *MODES_CFB_NewCtx(int32_t algId)
431 {
432     const EAL_SymMethod *method = EAL_GetSymMethod(algId);
433     if (method == NULL) {
434         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
435         return NULL;
436     }
437     MODES_CFB_Ctx *ctx = BSL_SAL_Calloc(1, sizeof(MODES_CFB_Ctx));
438     if (ctx == NULL) {
439         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
440         return ctx;
441     }
442     ctx->algId = algId;
443 
444     ctx->cfbCtx.modeCtx.ciphCtx = BSL_SAL_Calloc(1, method->ctxSize);
445     if (ctx->cfbCtx.modeCtx.ciphCtx  == NULL) {
446         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
447         BSL_SAL_Free(ctx);
448         return NULL;
449     }
450     ctx->cfbCtx.cacheIndex = 0;
451     uint8_t blockBits = method->blockSize * 8;
452     if (blockBits <= 128) {
453         ctx->cfbCtx.feedbackBits = blockBits;
454     } else {
455         ctx->cfbCtx.feedbackBits = 128;
456     }
457     ctx->cfbCtx.modeCtx.blockSize = method->blockSize;
458     ctx->cfbCtx.modeCtx.ciphMeth = method;
459     ctx->cfbCtx.modeCtx.offset = 0;
460     return ctx;
461 }
462 
MODES_CFB_InitCtx(MODES_CFB_Ctx * modeCtx,const uint8_t * key,uint32_t keyLen,const uint8_t * iv,uint32_t ivLen,bool enc)463 int32_t MODES_CFB_InitCtx(MODES_CFB_Ctx *modeCtx, const uint8_t *key, uint32_t keyLen, const uint8_t *iv,
464     uint32_t ivLen, bool enc)
465 {
466     modeCtx->cfbCtx.cacheIndex = 0;
467     modeCtx->enc = enc;
468     return MODES_CipherInitCommonCtx(&modeCtx->cfbCtx.modeCtx, modeCtx->cfbCtx.modeCtx.ciphMeth->setEncryptKey,
469         modeCtx->cfbCtx.modeCtx.ciphCtx, key, keyLen, iv, ivLen);
470 }
471 
MODES_CFB_Update(MODES_CFB_Ctx * modeCtx,const uint8_t * in,uint32_t inLen,uint8_t * out,uint32_t * outLen)472 int32_t MODES_CFB_Update(MODES_CFB_Ctx *modeCtx, const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen)
473 {
474     return MODES_CipherStreamProcess(modeCtx->enc ? MODES_CFB_Encrypt : MODES_CFB_Decrypt, &modeCtx->cfbCtx,
475         in, inLen, out, outLen);
476 }
477 
MODES_CFB_Final(MODES_CFB_Ctx * modeCtx,uint8_t * out,uint32_t * outLen)478 int32_t MODES_CFB_Final(MODES_CFB_Ctx *modeCtx, uint8_t *out, uint32_t *outLen)
479 {
480     (void) modeCtx;
481     (void) out;
482     *outLen = 0;
483     return CRYPT_SUCCESS;
484 }
485 
MODES_CFB_DeInitCtx(MODES_CFB_Ctx * modeCtx)486 int32_t MODES_CFB_DeInitCtx(MODES_CFB_Ctx *modeCtx)
487 {
488     if (modeCtx == NULL) {
489         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
490         return CRYPT_NULL_INPUT;
491     }
492     MODES_Clean(&modeCtx->cfbCtx.modeCtx);
493     BSL_SAL_CleanseData((void *)(modeCtx->cfbCtx.cipherCache[0]), DES_BLOCK_BYTE_NUM * 3); // 3 ciphertext caches
494     return CRYPT_SUCCESS;
495 }
496 
MODES_CFB_FreeCtx(MODES_CFB_Ctx * modeCtx)497 void MODES_CFB_FreeCtx(MODES_CFB_Ctx *modeCtx)
498 {
499     if (modeCtx == NULL) {
500         return ;
501     }
502     (void)MODES_CFB_DeInitCtx(modeCtx);
503     BSL_SAL_Free(modeCtx->cfbCtx.modeCtx.ciphCtx);
504     BSL_SAL_Free(modeCtx);
505 }
506 
MODES_CFB_InitCtxEx(MODES_CFB_Ctx * modeCtx,const uint8_t * key,uint32_t keyLen,const uint8_t * iv,uint32_t ivLen,void * param,bool enc)507 int32_t MODES_CFB_InitCtxEx(MODES_CFB_Ctx *modeCtx, const uint8_t *key, uint32_t keyLen, const uint8_t *iv,
508     uint32_t ivLen, void *param, bool enc)
509 {
510     (void) param;
511     if (modeCtx == NULL) {
512         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
513         return CRYPT_NULL_INPUT;
514     }
515     if (ivLen != modeCtx->cfbCtx.modeCtx.blockSize) {
516         BSL_ERR_PUSH_ERROR(CRYPT_MODES_IVLEN_ERROR);
517         return CRYPT_MODES_IVLEN_ERROR;
518     }
519     switch (modeCtx->algId) {
520         case CRYPT_CIPHER_SM4_CFB:
521 #ifdef HITLS_CRYPTO_SM4
522             return SM4_CFB_InitCtx(modeCtx, key, keyLen, iv, ivLen, enc);
523 #else
524             return CRYPT_EAL_ALG_NOT_SUPPORT;
525 #endif
526         default:
527             return MODES_CFB_InitCtx(modeCtx, key, keyLen, iv, ivLen, enc);
528     }
529 }
530 
MODES_CFB_UpdateEx(MODES_CFB_Ctx * modeCtx,const uint8_t * in,uint32_t inLen,uint8_t * out,uint32_t * outLen)531 int32_t MODES_CFB_UpdateEx(MODES_CFB_Ctx *modeCtx, const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen)
532 {
533     if (modeCtx == NULL) {
534         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
535         return CRYPT_NULL_INPUT;
536     }
537     switch (modeCtx->algId) {
538         case CRYPT_CIPHER_AES128_CFB:
539         case CRYPT_CIPHER_AES192_CFB:
540         case CRYPT_CIPHER_AES256_CFB:
541 #ifdef HITLS_CRYPTO_AES
542             return AES_CFB_Update(modeCtx, in, inLen, out, outLen);
543 #else
544             return CRYPT_EAL_ALG_NOT_SUPPORT;
545 #endif
546         case CRYPT_CIPHER_SM4_CFB:
547 #ifdef HITLS_CRYPTO_SM4
548             return SM4_CFB_Update(modeCtx, in, inLen, out, outLen);
549 #else
550             return CRYPT_EAL_ALG_NOT_SUPPORT;
551 #endif
552         default:
553             return MODES_CFB_Update(modeCtx, in, inLen, out, outLen);
554     }
555 }
556 
557 #endif