|
|
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.