Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/tomcrypt/src/modes/ctr/ctr_encrypt.c
5972 views
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 ctr_encrypt.c
13
CTR implementation, encrypt data, Tom St Denis
14
*/
15
16
17
#ifdef LTC_CTR_MODE
18
19
/**
20
CTR encrypt software implementation
21
@param pt Plaintext
22
@param ct [out] Ciphertext
23
@param len Length of plaintext (octets)
24
@param ctr CTR state
25
@return CRYPT_OK if successful
26
*/
27
static int _ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)
28
{
29
int x, err;
30
31
while (len) {
32
/* is the pad empty? */
33
if (ctr->padlen == ctr->blocklen) {
34
/* increment counter */
35
if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) {
36
/* 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) {
40
break;
41
}
42
}
43
} else {
44
/* big-endian */
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) {
48
break;
49
}
50
}
51
}
52
53
/* encrypt it */
54
if ((err = cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key)) != CRYPT_OK) {
55
return err;
56
}
57
ctr->padlen = 0;
58
}
59
#ifdef LTC_FAST
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));
64
}
65
pt += ctr->blocklen;
66
ct += ctr->blocklen;
67
len -= ctr->blocklen;
68
ctr->padlen = ctr->blocklen;
69
continue;
70
}
71
#endif
72
*ct++ = *pt++ ^ ctr->pad[ctr->padlen++];
73
--len;
74
}
75
return CRYPT_OK;
76
}
77
78
/**
79
CTR encrypt
80
@param pt Plaintext
81
@param ct [out] Ciphertext
82
@param len Length of plaintext (octets)
83
@param ctr CTR state
84
@return CRYPT_OK if successful
85
*/
86
int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)
87
{
88
int err, fr;
89
90
LTC_ARGCHK(pt != NULL);
91
LTC_ARGCHK(ct != NULL);
92
LTC_ARGCHK(ctr != NULL);
93
94
if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
95
return err;
96
}
97
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;
102
}
103
104
#ifdef LTC_FAST
105
if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) {
106
return CRYPT_INVALID_ARG;
107
}
108
#endif
109
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) {
115
return err;
116
}
117
pt += fr;
118
ct += fr;
119
len -= fr;
120
}
121
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) {
124
return err;
125
}
126
pt += (len / ctr->blocklen) * ctr->blocklen;
127
ct += (len / ctr->blocklen) * ctr->blocklen;
128
len %= ctr->blocklen;
129
}
130
}
131
132
return _ctr_encrypt(pt, ct, len, ctr);
133
}
134
135
#endif
136
137