Linux/MacOSX/FreeBSD: Support mounting partially encrypted system partitions/drivers in ReadOnly mode in order to allow troubleshooting in some cases.

This commit is contained in:
Mounir IDRASSI 2018-06-11 00:12:32 +02:00
parent 509c8288d0
commit d5dca62b04
No known key found for this signature in database
GPG Key ID: DD0C382D5FCFB8FC
3 changed files with 42 additions and 3 deletions

View File

@ -313,6 +313,7 @@ namespace VeraCrypt
if (options.NoKernelCrypto
|| !xts
|| algoNotSupported
|| volume->IsEncryptionNotCompleted ()
|| volume->GetProtectionType() == VolumeProtection::HiddenVolumeReadOnly)
{
throw NotApplicable (SRC_POS);

View File

@ -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;
}

View File

@ -113,6 +113,7 @@ namespace VeraCrypt
uint32 GetSaltSize () const { return Header->GetSaltSize(); }
size_t GetSectorSize () const { return SectorSize; }
uint64 GetSize () const { return VolumeDataSize; }
uint64 GetEncryptedSize () const { return EncryptedDataSize; }
uint64 GetTopWriteOffset () const { return TopWriteOffset; }
uint64 GetTotalDataRead () const { return TotalDataRead; }
uint64 GetTotalDataWritten () const { return TotalDataWritten; }
@ -127,6 +128,7 @@ namespace VeraCrypt
void ReadSectors (const BufferPtr &buffer, uint64 byteOffset);
void ReEncryptHeader (bool backupHeader, const ConstBufferPtr &newSalt, const ConstBufferPtr &newHeaderKey, shared_ptr <Pkcs5Kdf> newPkcs5Kdf);
void WriteSectors (const ConstBufferPtr &buffer, uint64 byteOffset);
bool IsEncryptionNotCompleted () const { return EncryptionNotCompleted; }
protected:
void CheckProtectedRange (uint64 writeHostOffset, uint64 writeLength);
@ -146,11 +148,13 @@ namespace VeraCrypt
uint64 VolumeHostSize;
uint64 VolumeDataOffset;
uint64 VolumeDataSize;
uint64 EncryptedDataSize;
uint64 TopWriteOffset;
uint64 TotalDataRead;
uint64 TotalDataWritten;
bool TrueCryptMode;
int Pim;
bool EncryptionNotCompleted;
private:
Volume (const Volume &);