]> pd.if.org Git - zpackage/blob - cbc_encrypt.c
00d85fcbc8f311448e3bee1a16c8f19e00c829e0
[zpackage] / cbc_encrypt.c
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 */
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$ */