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