Mercurial > dropbear
comparison src/modes/ctr/ctr_encrypt.c @ 191:1c15b283127b libtomcrypt-orig
Import of libtomcrypt 1.02 with manual path rename rearrangement etc
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 06 May 2005 13:23:02 +0000 |
parents | |
children | 39d5d58461d6 |
comparison
equal
deleted
inserted
replaced
143:5d99163f7e32 | 191:1c15b283127b |
---|---|
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, [email protected], http://libtomcrypt.org | |
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 CTR | |
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 < 0 || 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 cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key); | |
56 len %= ctr->blocklen; | |
57 } | |
58 | |
59 while (len) { | |
60 /* is the pad empty? */ | |
61 if (ctr->padlen == ctr->blocklen) { | |
62 /* increment counter */ | |
63 if (ctr->mode == 0) { | |
64 /* little-endian */ | |
65 for (x = 0; x < ctr->blocklen; x++) { | |
66 ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; | |
67 if (ctr->ctr[x] != (unsigned char)0) { | |
68 break; | |
69 } | |
70 } | |
71 } else { | |
72 /* big-endian */ | |
73 for (x = ctr->blocklen-1; x >= 0; x--) { | |
74 ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; | |
75 if (ctr->ctr[x] != (unsigned char)0) { | |
76 break; | |
77 } | |
78 } | |
79 } | |
80 | |
81 /* encrypt it */ | |
82 cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key); | |
83 ctr->padlen = 0; | |
84 } | |
85 #ifdef LTC_FAST | |
86 if (ctr->padlen == 0 && len >= (unsigned long)ctr->blocklen) { | |
87 for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) { | |
88 *((LTC_FAST_TYPE*)((unsigned char *)ct + x)) = *((LTC_FAST_TYPE*)((unsigned char *)pt + x)) ^ | |
89 *((LTC_FAST_TYPE*)((unsigned char *)ctr->pad + x)); | |
90 } | |
91 pt += ctr->blocklen; | |
92 ct += ctr->blocklen; | |
93 len -= ctr->blocklen; | |
94 ctr->padlen = ctr->blocklen; | |
95 continue; | |
96 } | |
97 #endif | |
98 *ct++ = *pt++ ^ ctr->pad[ctr->padlen++]; | |
99 --len; | |
100 } | |
101 return CRYPT_OK; | |
102 } | |
103 | |
104 #endif |