From d5dca62b044290475d9dd793e4abb58fbfe776d5 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Mon, 11 Jun 2018 00:12:32 +0200 Subject: Linux/MacOSX/FreeBSD: Support mounting partially encrypted system partitions/drivers in ReadOnly mode in order to allow troubleshooting in some cases. --- src/Volume/Volume.cpp | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) (limited to 'src/Volume/Volume.cpp') diff --git a/src/Volume/Volume.cpp b/src/Volume/Volume.cpp index d3ef2067..d4d799d1 100644 --- a/src/Volume/Volume.cpp +++ b/src/Volume/Volume.cpp @@ -24,12 +24,15 @@ namespace VeraCrypt Volume::Volume () : HiddenVolumeProtectionTriggered (false), SystemEncryption (false), + VolumeDataOffset (0), VolumeDataSize (0), + EncryptedDataSize (0), TopWriteOffset (0), TotalDataRead (0), TotalDataWritten (0), TrueCryptMode (false), - Pim (0) + Pim (0), + EncryptionNotCompleted (false) { } @@ -206,6 +209,7 @@ namespace VeraCrypt VolumeDataOffset = layout->GetDataOffset (VolumeHostSize); VolumeDataSize = layout->GetDataSize (VolumeHostSize); + EncryptedDataSize = header->GetEncryptedAreaLength(); Header = header; Layout = layout; @@ -215,7 +219,11 @@ namespace VeraCrypt if (layout->HasDriveHeader()) { if (header->GetEncryptedAreaLength() != header->GetVolumeDataSize()) - throw VolumeEncryptionNotCompleted (SRC_POS); + { + EncryptionNotCompleted = true; + // we avoid writing data to the partition since it is only partially encrypted + Protection = VolumeProtection::ReadOnly; + } uint64 partitionStartOffset = VolumeFile->GetPartitionDeviceStartOffset(); @@ -223,6 +231,8 @@ namespace VeraCrypt || partitionStartOffset >= header->GetEncryptedAreaStart() + header->GetEncryptedAreaLength()) throw PasswordIncorrect (SRC_POS); + EncryptedDataSize -= partitionStartOffset - header->GetEncryptedAreaStart(); + mode.SetSectorOffset (partitionStartOffset / ENCRYPTION_DATA_UNIT_SIZE); } @@ -313,7 +323,31 @@ namespace VeraCrypt if (VolumeFile->ReadAt (buffer, hostOffset) != length) throw MissingVolumeData (SRC_POS); - EA->DecryptSectors (buffer, hostOffset / SectorSize, length / SectorSize, SectorSize); + if (EncryptionNotCompleted) + { + // if encryption is not complete, we decrypt only the encrypted sectors + if (hostOffset < EncryptedDataSize) + { + size_t bufferOffset = 0; + + // first sector is not encrypted in case of incomplete encryption + if (hostOffset == 0) + { + bufferOffset = (size_t) SectorSize; + hostOffset += SectorSize; + length -= SectorSize; + } + + if (length && (hostOffset < EncryptedDataSize)) + { + uint64 encryptedLength = VC_MIN (length, (EncryptedDataSize - hostOffset)); + + EA->DecryptSectors (buffer.GetRange (bufferOffset, encryptedLength), hostOffset / SectorSize, encryptedLength / SectorSize, SectorSize); + } + } + } + else + EA->DecryptSectors (buffer, hostOffset / SectorSize, length / SectorSize, SectorSize); TotalDataRead += length; } -- cgit v1.2.3