1 // SPDX-License-Identifier: BSD-2-Clause
2 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3 *
4 * LibTomCrypt is a library that provides various cryptographic
5 * algorithms in a highly modular and flexible manner.
6 *
7 * The library is free for all purposes without any express
8 * guarantee it works.
9 */
10 #include "tomcrypt_private.h"
11
12 /**
13 @file cbc_encrypt.c
14 CBC implementation, encrypt block, Tom St Denis
15 */
16
17
18 #ifdef LTC_CBC_MODE
19
20 /**
21 CBC encrypt
22 @param pt Plaintext
23 @param ct [out] Ciphertext
24 @param len The number of bytes to process (must be multiple of block length)
25 @param cbc CBC state
26 @return CRYPT_OK if successful
27 */
cbc_encrypt(const unsigned char * pt,unsigned char * ct,unsigned long len,symmetric_CBC * cbc)28 int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CBC *cbc)
29 {
30 int x, err;
31
32 LTC_ARGCHK(pt != NULL);
33 LTC_ARGCHK(ct != NULL);
34 LTC_ARGCHK(cbc != NULL);
35
36 if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
37 return err;
38 }
39
40 /* is blocklen valid? */
41 if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV)) {
42 return CRYPT_INVALID_ARG;
43 }
44
45 if (len % cbc->blocklen) {
46 return CRYPT_INVALID_ARG;
47 }
48 #ifdef LTC_FAST
49 if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) {
50 return CRYPT_INVALID_ARG;
51 }
52 #endif
53
54 if (cipher_descriptor[cbc->cipher]->accel_cbc_encrypt != NULL) {
55 return cipher_descriptor[cbc->cipher]->accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key);
56 }
57 while (len) {
58 /* xor IV against plaintext */
59 #if defined(LTC_FAST)
60 for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
61 *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) ^= *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x));
62 }
63 #else
64 for (x = 0; x < cbc->blocklen; x++) {
65 cbc->IV[x] ^= pt[x];
66 }
67 #endif
68
69 /* encrypt */
70 if ((err = cipher_descriptor[cbc->cipher]->ecb_encrypt(cbc->IV, ct, &cbc->key)) != CRYPT_OK) {
71 return err;
72 }
73
74 /* store IV [ciphertext] for a future block */
75 #if defined(LTC_FAST)
76 for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
77 *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x));
78 }
79 #else
80 for (x = 0; x < cbc->blocklen; x++) {
81 cbc->IV[x] = ct[x];
82 }
83 #endif
84
85 ct += cbc->blocklen;
86 pt += cbc->blocklen;
87 len -= cbc->blocklen;
88 }
89 return CRYPT_OK;
90 }
91
92 #endif
93
94 /* ref: $Format:%D$ */
95 /* git commit: $Format:%H$ */
96 /* commit time: $Format:%ai$ */
97