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