VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Volume/EncryptionModeCBC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Volume/EncryptionModeCBC.cpp')
-rw-r--r--src/Volume/EncryptionModeCBC.cpp335
1 files changed, 0 insertions, 335 deletions
diff --git a/src/Volume/EncryptionModeCBC.cpp b/src/Volume/EncryptionModeCBC.cpp
deleted file mode 100644
index 2892986b..00000000
--- a/src/Volume/EncryptionModeCBC.cpp
+++ /dev/null
@@ -1,335 +0,0 @@
1/*
2 Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
3
4 Governed by the TrueCrypt License 3.0 the full text of which is contained in
5 the file License.txt included in TrueCrypt binary and source code distribution
6 packages.
7*/
8
9#include "Platform/Memory.h"
10#include "Common/Crc.h"
11#include "Common/Endian.h"
12#include "EncryptionModeCBC.h"
13
14namespace VeraCrypt
15{
16 void EncryptionModeCBC::Decrypt (byte *data, uint64 length) const
17 {
18 if_debug (ValidateState ());
19 if_debug (ValidateParameters (data, length));
20
21 if (IsOuterCBC (Ciphers))
22 {
23 DecryptBuffer (data, length, Ciphers, (uint32 *) IV.Ptr(), (uint32 *) (IV.Ptr() + WhiteningIVOffset));
24 }
25 else
26 {
27 for (CipherList::const_reverse_iterator iCipherList = Ciphers.rbegin();
28 iCipherList != Ciphers.rend();
29 ++iCipherList)
30 {
31 CipherList cl;
32 cl.push_back (*iCipherList);
33
34 DecryptBuffer (data, length, cl, (uint32 *) IV.Ptr(), (uint32 *) (IV.Ptr() + WhiteningIVOffset));
35 }
36 }
37 }
38
39 void EncryptionModeCBC::DecryptBuffer (byte *data, uint64 length, const CipherList &ciphers, const uint32 *iv, const uint32 *whitening) const
40 {
41 size_t blockSize = ciphers.front()->GetBlockSize();
42 if (blockSize != 8 && blockSize != 16)
43 throw ParameterIncorrect (SRC_POS);
44
45 uint32 *data32 = (uint32 *) data;
46 uint32 bufIV[4];
47 uint32 ct[4];
48 uint64 i;
49
50 bufIV[0] = iv[0];
51 bufIV[1] = iv[1];
52 if (blockSize == 16)
53 {
54 bufIV[2] = iv[2];
55 bufIV[3] = iv[3];
56 }
57
58 for (i = 0; i < length / blockSize; i++)
59 {
60 // Dewhitening
61 data32[0] ^= whitening[0];
62 data32[1] ^= whitening[1];
63 if (blockSize == 16)
64 {
65 data32[2] ^= whitening[0];
66 data32[3] ^= whitening[1];
67 }
68
69 // CBC
70 ct[0] = data32[0];
71 ct[1] = data32[1];
72 if (blockSize == 16)
73 {
74 ct[2] = data32[2];
75 ct[3] = data32[3];
76 }
77
78 for (CipherList::const_reverse_iterator iCipherList = ciphers.rbegin();
79 iCipherList != ciphers.rend();
80 ++iCipherList)
81 {
82 const Cipher &c = **iCipherList;
83
84 if (c.GetBlockSize () != blockSize)
85 throw ParameterIncorrect (SRC_POS);
86
87 c.DecryptBlock ((byte *) data32);
88 }
89
90 // CBC
91 data32[0] ^= bufIV[0];
92 data32[1] ^= bufIV[1];
93 bufIV[0] = ct[0];
94 bufIV[1] = ct[1];
95 if (blockSize == 16)
96 {
97 data32[2] ^= bufIV[2];
98 data32[3] ^= bufIV[3];
99 bufIV[2] = ct[2];
100 bufIV[3] = ct[3];
101 }
102
103 data32 += blockSize / sizeof(*data32);
104 }
105
106 Memory::Erase (bufIV, sizeof (bufIV));
107 Memory::Erase (ct, sizeof (ct));
108 }
109
110 void EncryptionModeCBC::DecryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const
111 {
112 if_debug (ValidateState ());
113 if_debug (ValidateParameters (data, sectorCount, sectorSize));
114
115 uint32 sectorIV[4];
116 uint32 sectorWhitening[2];
117
118 while (sectorCount--)
119 {
120 if (IsOuterCBC (Ciphers))
121 {
122 InitSectorIVAndWhitening (sectorIndex, Ciphers.front()->GetBlockSize(), (uint64 *) IV.Ptr(), sectorIV, sectorWhitening);
123 DecryptBuffer (data, sectorSize, Ciphers, sectorIV, sectorWhitening);
124 }
125 else
126 {
127 for (CipherList::const_reverse_iterator iCipherList = Ciphers.rbegin();
128 iCipherList != Ciphers.rend();
129 ++iCipherList)
130 {
131 const Cipher &c = **iCipherList;
132 CipherList cl;
133 cl.push_back (*iCipherList);
134
135 InitSectorIVAndWhitening (sectorIndex, c.GetBlockSize(), (uint64 *) IV.Ptr(), sectorIV, sectorWhitening);
136 DecryptBuffer (data, sectorSize, cl, sectorIV, sectorWhitening);
137 }
138 }
139
140 data += sectorSize;
141 sectorIndex++;
142 }
143
144 Memory::Erase (sectorIV, sizeof (sectorIV));
145 Memory::Erase (sectorWhitening, sizeof (sectorWhitening));
146 }
147
148 void EncryptionModeCBC::Encrypt (byte *data, uint64 length) const
149 {
150 if_debug (ValidateState ());
151 if_debug (ValidateParameters (data, length));
152
153 if (IsOuterCBC (Ciphers))
154 {
155 EncryptBuffer (data, length, Ciphers, (uint32 *) IV.Ptr(), (uint32 *) (IV.Ptr() + WhiteningIVOffset));
156 }
157 else
158 {
159 for (CipherList::const_iterator iCipherList = Ciphers.begin();
160 iCipherList != Ciphers.end();
161 ++iCipherList)
162 {
163 CipherList cl;
164 cl.push_back (*iCipherList);
165
166 EncryptBuffer (data, length, cl, (uint32 *) IV.Ptr(), (uint32 *) (IV.Ptr() + WhiteningIVOffset));
167 }
168 }
169 }
170
171 void EncryptionModeCBC::EncryptBuffer (byte *data, uint64 length, const CipherList &ciphers, const uint32 *iv, const uint32 *whitening) const
172 {
173 size_t blockSize = ciphers.front()->GetBlockSize();
174 if (blockSize != 8 && blockSize != 16)
175 throw ParameterIncorrect (SRC_POS);
176
177 uint32 *data32 = (uint32 *) data;
178 uint32 bufIV[4];
179 uint64 i;
180
181 bufIV[0] = iv[0];
182 bufIV[1] = iv[1];
183 if (blockSize == 16)
184 {
185 bufIV[2] = iv[2];
186 bufIV[3] = iv[3];
187 }
188
189 for (i = 0; i < length / blockSize; i++)
190 {
191 data32[0] ^= bufIV[0];
192 data32[1] ^= bufIV[1];
193 if (blockSize == 16)
194 {
195 data32[2] ^= bufIV[2];
196 data32[3] ^= bufIV[3];
197 }
198
199 for (CipherList::const_iterator iCipherList = ciphers.begin();
200 iCipherList != ciphers.end();
201 ++iCipherList)
202 {
203 const Cipher &c = **iCipherList;
204
205 if (c.GetBlockSize () != blockSize)
206 throw ParameterIncorrect (SRC_POS);
207
208 c.EncryptBlock ((byte *) data32);
209 }
210
211 bufIV[0] = data32[0];
212 bufIV[1] = data32[1];
213 if (blockSize == 16)
214 {
215 bufIV[2] = data32[2];
216 bufIV[3] = data32[3];
217 }
218
219 data32[0] ^= whitening[0];
220 data32[1] ^= whitening[1];
221 if (blockSize == 16)
222 {
223 data32[2] ^= whitening[0];
224 data32[3] ^= whitening[1];
225 }
226
227 data32 += blockSize / sizeof(*data32);
228 }
229
230 Memory::Erase (bufIV, sizeof (bufIV));
231 }
232
233 void EncryptionModeCBC::EncryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const
234 {
235 if_debug (ValidateState ());
236 if_debug (ValidateParameters (data, sectorCount, sectorSize));
237
238 uint32 sectorIV[4];
239 uint32 sectorWhitening[2];
240
241 while (sectorCount--)
242 {
243 if (IsOuterCBC (Ciphers))
244 {
245 InitSectorIVAndWhitening (sectorIndex, Ciphers.front()->GetBlockSize(), (uint64 *) IV.Ptr(), sectorIV, sectorWhitening);
246 EncryptBuffer (data, sectorSize, Ciphers, sectorIV, sectorWhitening);
247 }
248 else
249 {
250 for (CipherList::const_iterator iCipherList = Ciphers.begin();
251 iCipherList != Ciphers.end();
252 ++iCipherList)
253 {
254 const Cipher &c = **iCipherList;
255 CipherList cl;
256 cl.push_back (*iCipherList);
257
258 InitSectorIVAndWhitening (sectorIndex, c.GetBlockSize(), (uint64 *) IV.Ptr(), sectorIV, sectorWhitening);
259 EncryptBuffer (data, sectorSize, cl, sectorIV, sectorWhitening);
260 }
261 }
262
263 data += sectorSize;
264 sectorIndex++;
265 }
266
267 Memory::Erase (sectorIV, sizeof (sectorIV));
268 Memory::Erase (sectorWhitening, sizeof (sectorWhitening));
269 }
270
271 void EncryptionModeCBC::InitSectorIVAndWhitening (uint64 sectorIndex, size_t blockSize, const uint64 *ivSeed, uint32 *iv, uint32 *whitening) const
272 {
273 if (blockSize != 8 && blockSize != 16)
274 throw ParameterIncorrect (SRC_POS);
275
276 uint64 iv64[4];
277 uint32 *iv32 = (uint32 *) iv64;
278
279 iv64[0] = ivSeed[0] ^ Endian::Little (sectorIndex);
280 iv64[1] = ivSeed[1] ^ Endian::Little (sectorIndex);
281 iv64[2] = ivSeed[2] ^ Endian::Little (sectorIndex);
282 if (blockSize == 16)
283 {
284 iv64[3] = ivSeed[3] ^ Endian::Little (sectorIndex);
285 }
286
287 iv[0] = iv32[0];
288 iv[1] = iv32[1];
289
290 if (blockSize == 8)
291 {
292 whitening[0] = Endian::Little ( crc32int ( &iv32[2] ) ^ crc32int ( &iv32[5] ) );
293 whitening[1] = Endian::Little ( crc32int ( &iv32[3] ) ^ crc32int ( &iv32[4] ) );
294 }
295 else
296 {
297 iv[2] = iv32[2];
298 iv[3] = iv32[3];
299
300 whitening[0] = Endian::Little ( crc32int ( &iv32[4] ) ^ crc32int ( &iv32[7] ) );
301 whitening[1] = Endian::Little ( crc32int ( &iv32[5] ) ^ crc32int ( &iv32[6] ) );
302 }
303 }
304
305 bool EncryptionModeCBC::IsOuterCBC (const CipherList &ciphers) const
306 {
307 if (ciphers.size() < 2)
308 return false;
309
310 size_t blockSize = ciphers.front()->GetBlockSize();
311
312 for (CipherList::const_iterator iCipherList = ciphers.begin();
313 iCipherList != ciphers.end();
314 ++iCipherList)
315 {
316 const Cipher &c = **iCipherList;
317 if (c.GetBlockSize() != blockSize)
318 return false;
319 }
320
321 return true;
322 }
323
324 void EncryptionModeCBC::SetKey (const ConstBufferPtr &key)
325 {
326 if (key.Size() != GetKeySize ())
327 throw ParameterIncorrect (SRC_POS);
328
329 if (!KeySet)
330 IV.Allocate (GetKeySize ());
331
332 IV.CopyFrom (key);
333 KeySet = true;
334 }
335}