diff options
Diffstat (limited to 'src/Volume/EncryptionModeCBC.cpp')
-rw-r--r-- | src/Volume/EncryptionModeCBC.cpp | 335 |
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 | |||
14 | namespace 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 | } | ||