1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
6 * The library is free for all purposes without any express
13 CTR implementation, encrypt data, Tom St Denis
20 CTR encrypt software implementation
22 @param ct [out] Ciphertext
23 @param len Length of plaintext (octets)
25 @return CRYPT_OK if successful
27 static int _ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)
32 /* is the pad empty? */
33 if (ctr->padlen == ctr->blocklen) {
34 /* increment counter */
35 if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) {
37 for (x = 0; x < ctr->ctrlen; x++) {
38 ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
39 if (ctr->ctr[x] != (unsigned char)0) {
45 for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) {
46 ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
47 if (ctr->ctr[x] != (unsigned char)0) {
54 if ((err = cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key)) != CRYPT_OK) {
60 if ((ctr->padlen == 0) && (len >= (unsigned long)ctr->blocklen)) {
61 for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) {
62 *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) ^
63 *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ctr->pad + x));
68 ctr->padlen = ctr->blocklen;
72 *ct++ = *pt++ ^ ctr->pad[ctr->padlen++];
81 @param ct [out] Ciphertext
82 @param len Length of plaintext (octets)
84 @return CRYPT_OK if successful
86 int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)
90 LTC_ARGCHK(pt != NULL);
91 LTC_ARGCHK(ct != NULL);
92 LTC_ARGCHK(ctr != NULL);
94 if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
98 /* is blocklen/padlen valid? */
99 if ((ctr->blocklen < 1) || (ctr->blocklen > (int)sizeof(ctr->ctr)) ||
100 (ctr->padlen < 0) || (ctr->padlen > (int)sizeof(ctr->pad))) {
101 return CRYPT_INVALID_ARG;
105 if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) {
106 return CRYPT_INVALID_ARG;
110 /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */
111 if ((cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL) && (len >= (unsigned long)ctr->blocklen)) {
112 if (ctr->padlen < ctr->blocklen) {
113 fr = ctr->blocklen - ctr->padlen;
114 if ((err = _ctr_encrypt(pt, ct, fr, ctr)) != CRYPT_OK) {
122 if (len >= (unsigned long)ctr->blocklen) {
123 if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) {
126 pt += (len / ctr->blocklen) * ctr->blocklen;
127 ct += (len / ctr->blocklen) * ctr->blocklen;
128 len %= ctr->blocklen;
132 return _ctr_encrypt(pt, ct, len, ctr);
137 /* ref: $Format:%D$ */
138 /* git commit: $Format:%H$ */
139 /* commit time: $Format:%ai$ */