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