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 * Tom St Denis, tomstdenis (at) gmail.com, http://libtomcrypt.com 10 */ 11 #include "tomcrypt.h" 12 13 /** 14 @file ctr_encrypt.c 15 CTR implementation, encrypt data, Tom St Denis 16 */ 17 18 19 #ifdef LTC_CTR_MODE 20 21 /** 22 CTR encrypt 23 @param pt Plaintext 24 @param ct [out] Ciphertext 25 @param len Length of plaintext (octets) 26 @param ctr CTR state 27 @return CRYPT_OK if successful 28 */ 29 int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr) 30 { 31 int x, err; 32 33 LTC_ARGCHK(pt != NULL); 34 LTC_ARGCHK(ct != NULL); 35 LTC_ARGCHK(ctr != NULL); 36 37 if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { 38 return err; 39 } 40 41 /* is blocklen/padlen valid? */ 42 if (ctr->blocklen < 1 || ctr->blocklen > (int)sizeof(ctr->ctr) || 43 ctr->padlen < 0 || ctr->padlen > (int)sizeof(ctr->pad)) { 44 return CRYPT_INVALID_ARG; 45 } 46 47 #ifdef LTC_FAST 48 if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) { 49 return CRYPT_INVALID_ARG; 50 } 51 #endif 52 53 /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */ 54 if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) { 55 if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) { 56 return err; 57 } 58 len %= ctr->blocklen; 59 } 60 61 while (len) { 62 /* is the pad empty? */ 63 if (ctr->padlen == ctr->blocklen) { 64 /* increment counter */ 65 if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) { 66 /* little-endian */ 67 for (x = 0; x < ctr->blocklen; x++) { 68 ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; 69 if (ctr->ctr[x] != (unsigned char)0) { 70 break; 71 } 72 } 73 } else { 74 /* big-endian */ 75 for (x = ctr->blocklen-1; x >= 0; x--) { 76 ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; 77 if (ctr->ctr[x] != (unsigned char)0) { 78 break; 79 } 80 } 81 } 82 83 /* encrypt it */ 84 if ((err = cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key)) != CRYPT_OK) { 85 return err; 86 } 87 ctr->padlen = 0; 88 } 89 #ifdef LTC_FAST 90 if (ctr->padlen == 0 && len >= (unsigned long)ctr->blocklen) { 91 for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) { 92 *((LTC_FAST_TYPE*)((unsigned char *)ct + x)) = *((LTC_FAST_TYPE*)((unsigned char *)pt + x)) ^ 93 *((LTC_FAST_TYPE*)((unsigned char *)ctr->pad + x)); 94 } 95 pt += ctr->blocklen; 96 ct += ctr->blocklen; 97 len -= ctr->blocklen; 98 ctr->padlen = ctr->blocklen; 99 continue; 100 } 101 #endif 102 *ct++ = *pt++ ^ ctr->pad[ctr->padlen++]; 103 --len; 104 } 105 return CRYPT_OK; 106 } 107 108 #endif 109 110 /* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_encrypt.c,v $ */ 111 /* $Revision: 1.20 $ */ 112 /* $Date: 2006/11/21 00:18:23 $ */ 113