|
|
1.1 root 1: /*
2: Copyright (c) 2008 TrueCrypt Foundation. All rights reserved.
3:
4: Governed by the TrueCrypt License 2.4 the full text of which is contained
5: in the file License.txt included in TrueCrypt binary and source code
6: distribution packages.
7: */
8:
9: #ifndef TC_WINDOWS
10: #include <errno.h>
11: #endif
12: #include "EncryptionModeLRW.h"
13: #include "EncryptionModeXTS.h"
14: #include "Volume.h"
15: #include "VolumeHeader.h"
16: #include "VolumeLayout.h"
17:
18: namespace TrueCrypt
19: {
20: Volume::Volume ()
21: : HiddenVolumeProtectionTriggered (false),
22: VolumeDataSize (0),
23: TotalDataRead (0),
24: TotalDataWritten (0)
25: {
26: }
27:
28: Volume::~Volume ()
29: {
30: }
31:
32: void Volume::CheckProtectedRange (uint64 writeHostOffset, uint64 writeLength)
33: {
34: uint64 writeHostEndOffset = writeHostOffset + writeLength - 1;
35:
36: if ((writeHostOffset < ProtectedRangeStart) ? (writeHostEndOffset >= ProtectedRangeStart) : (writeHostOffset <= ProtectedRangeEnd - 1))
37: {
38: HiddenVolumeProtectionTriggered = true;
39: throw VolumeProtected (SRC_POS);
40: }
41: }
42:
43: void Volume::Close ()
44: {
45: if (VolumeFile.get() == nullptr)
46: throw NotInitialized (SRC_POS);
47:
48: VolumeFile.reset();
49: }
50:
51: shared_ptr <EncryptionAlgorithm> Volume::GetEncryptionAlgorithm () const
52: {
53: if_debug (ValidateState ());
54: return EA;
55: }
56:
57: shared_ptr <EncryptionMode> Volume::GetEncryptionMode () const
58: {
59: if_debug (ValidateState ());
60: return EA->GetMode();
61: }
62:
63: void Volume::Open (const VolumePath &volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection, shared_ptr <VolumePassword> protectionPassword, shared_ptr <KeyfileList> protectionKeyfiles, bool sharedAccessAllowed, VolumeType::Enum volumeType)
64: {
65: make_shared_auto (File, file);
66:
67: File::FileOpenFlags flags = (preserveTimestamps ? File::PreserveTimestamps : File::FlagsNone);
68:
69: try
70: {
71: if (protection == VolumeProtection::ReadOnly)
72: file->Open (volumePath, File::OpenRead, File::ShareRead, flags);
73: else
74: file->Open (volumePath, File::OpenReadWrite, File::ShareNone, flags);
75: }
76: catch (SystemException &e)
77: {
78: if (e.GetErrorCode() ==
79: #ifdef TC_WINDOWS
80: ERROR_SHARING_VIOLATION)
81: #else
82: EAGAIN)
83: #endif
84: {
85: if (!sharedAccessAllowed)
86: throw VolumeHostInUse (SRC_POS);
87:
88: file->Open (volumePath, protection == VolumeProtection::ReadOnly ? File::OpenRead : File::OpenReadWrite, File::ShareReadWriteIgnoreLock, flags);
89: }
90: else
91: throw;
92: }
93:
94: return Open (file, password, keyfiles, protection, protectionPassword, protectionKeyfiles, volumeType);
95: }
96:
97: void Volume::Open (shared_ptr <File> volumeFile, shared_ptr <VolumePassword> password, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection, shared_ptr <VolumePassword> protectionPassword, shared_ptr <KeyfileList> protectionKeyfiles, VolumeType::Enum volumeType)
98: {
99: if (!volumeFile)
100: throw ParameterIncorrect (SRC_POS);
101:
102: Protection = protection;
103: VolumeFile = volumeFile;
104:
105: try
106: {
107: VolumeHostSize = VolumeFile->Length();
108: shared_ptr <VolumePassword> passwordKey = Keyfile::ApplyListToPassword (keyfiles, password);
109:
110: // Test volume layouts
111: foreach (shared_ptr <VolumeLayout> layout, VolumeLayout::GetAvailableLayouts (volumeType))
112: {
113: if (layout->GetHeaderOffset() >= 0)
114: VolumeFile->SeekAt (layout->GetHeaderOffset());
115: else
116: VolumeFile->SeekEnd (layout->GetHeaderOffset());
117:
118: SecureBuffer headerBuffer (layout->GetHeaderSize());
119:
120: if (VolumeFile->Read (headerBuffer) != layout->GetHeaderSize())
121: throw MissingVolumeData (SRC_POS);
122:
123: shared_ptr <VolumeHeader> header = layout->GetHeader();
124:
125: if (header->Decrypt (headerBuffer, *passwordKey, layout->GetSupportedEncryptionAlgorithms(), layout->GetSupportedEncryptionModes ()))
126: {
127: // Header decrypted
128: Type = layout->GetType();
129: SectorSize = header->GetSectorSize();
130: VolumeDataOffset = layout->GetDataOffset (VolumeHostSize);
131: VolumeDataSize = layout->GetDataSize (VolumeHostSize);
132:
133: Header = header;
134: Layout = layout;
135: EA = header->GetEncryptionAlgorithm();
136: EncryptionMode &mode = *EA->GetMode();
137:
138: if (typeid (mode) == typeid (EncryptionModeLRW))
139: mode.SetSectorOffset (VolumeDataOffset / SectorSize);
140:
141: // Volume protection
142: if (Protection == VolumeProtection::HiddenVolumeReadOnly)
143: {
144: if (Type == VolumeType::Hidden)
145: Protection = VolumeProtection::ReadOnly;
146: else
147: {
148: try
149: {
150: Volume protectedVolume;
151:
152: protectedVolume.Open (VolumeFile,
153: protectionPassword, protectionKeyfiles,
154: VolumeProtection::ReadOnly,
155: shared_ptr <VolumePassword> (), shared_ptr <KeyfileList> (),
156: VolumeType::Hidden);
157:
158: if (protectedVolume.GetType() != VolumeType::Hidden)
159: ParameterIncorrect (SRC_POS);
160:
161: ProtectedRangeStart = protectedVolume.VolumeDataOffset;
162: ProtectedRangeEnd = protectedVolume.VolumeDataOffset + protectedVolume.VolumeDataSize + protectedVolume.Layout->GetHeaderSize();
163: }
164: catch (PasswordException&)
165: {
166: if (protectionKeyfiles && !protectionKeyfiles->empty())
167: throw ProtectionPasswordKeyfilesIncorrect (SRC_POS);
168: throw ProtectionPasswordIncorrect (SRC_POS);
169: }
170: }
171: }
172: return;
173: }
174: }
175: if (keyfiles && !keyfiles->empty())
176: throw PasswordKeyfilesIncorrect (SRC_POS);
177: throw PasswordIncorrect (SRC_POS);
178: }
179: catch (...)
180: {
181: Close();
182: throw;
183: }
184: }
185:
186: void Volume::ReadSectors (const BufferPtr &buffer, uint64 byteOffset)
187: {
188: if_debug (ValidateState ());
189:
190: uint64 length = buffer.Size();
191: uint64 hostOffset = VolumeDataOffset + byteOffset;
192:
193: if (length % SectorSize != 0 || byteOffset % SectorSize != 0)
194: throw ParameterIncorrect (SRC_POS);
195:
196: if (VolumeFile->ReadAt (buffer, hostOffset) != length)
197: throw MissingVolumeData (SRC_POS);
198:
199: EA->DecryptSectors (buffer, hostOffset / SectorSize, length / SectorSize, SectorSize);
200:
201: TotalDataRead += length;
202: }
203:
204: void Volume::ReEncryptHeader (const ConstBufferPtr &newSalt, const ConstBufferPtr &newHeaderKey, shared_ptr <Pkcs5Kdf> newPkcs5Kdf)
205: {
206: if_debug (ValidateState ());
207:
208: if (Protection == VolumeProtection::ReadOnly)
209: throw VolumeReadOnly (SRC_POS);
210:
211: SecureBuffer newHeaderBuffer (Layout->GetHeaderSize());
212:
213: Header->EncryptNew (newHeaderBuffer, newSalt, newHeaderKey, newPkcs5Kdf);
214:
215: if (Layout->GetHeaderOffset() >= 0)
216: VolumeFile->SeekAt (Layout->GetHeaderOffset());
217: else
218: VolumeFile->SeekEnd (Layout->GetHeaderOffset());
219:
220: VolumeFile->Write (newHeaderBuffer);
221: }
222:
223: void Volume::ValidateState () const
224: {
225: if (VolumeFile.get() == nullptr)
226: throw NotInitialized (SRC_POS);
227: }
228:
229: void Volume::WriteSectors (const ConstBufferPtr &buffer, uint64 byteOffset)
230: {
231: if_debug (ValidateState ());
232:
233: uint64 length = buffer.Size();
234: uint64 hostOffset = VolumeDataOffset + byteOffset;
235:
236: if (length % SectorSize != 0
237: || byteOffset % SectorSize != 0
238: || byteOffset + length > VolumeDataSize)
239: throw ParameterIncorrect (SRC_POS);
240:
241: if (Protection == VolumeProtection::ReadOnly)
242: throw VolumeReadOnly (SRC_POS);
243:
244: if (HiddenVolumeProtectionTriggered)
245: throw VolumeProtected (SRC_POS);
246:
247: if (Protection == VolumeProtection::HiddenVolumeReadOnly)
248: CheckProtectedRange (hostOffset, length);
249:
250: SecureBuffer encBuf (buffer.Size());
251: encBuf.CopyFrom (buffer);
252:
253: EA->EncryptSectors (encBuf, hostOffset / SectorSize, length / SectorSize, SectorSize);
254: VolumeFile->WriteAt (encBuf, hostOffset);
255:
256: TotalDataWritten += length;
257: }
258: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.