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 if (options.NoKernelCrypto
|| !xts || !xts
|| algoNotSupported || algoNotSupported
|| volume->IsEncryptionNotCompleted ()
|| volume->GetProtectionType() == VolumeProtection::HiddenVolumeReadOnly) || volume->GetProtectionType() == VolumeProtection::HiddenVolumeReadOnly)
{ {
throw NotApplicable (SRC_POS); throw NotApplicable (SRC_POS);

View File

@ -24,12 +24,15 @@ namespace VeraCrypt
Volume::Volume () Volume::Volume ()
: HiddenVolumeProtectionTriggered (false), : HiddenVolumeProtectionTriggered (false),
SystemEncryption (false), SystemEncryption (false),
VolumeDataOffset (0),
VolumeDataSize (0), VolumeDataSize (0),
EncryptedDataSize (0),
TopWriteOffset (0), TopWriteOffset (0),
TotalDataRead (0), TotalDataRead (0),
TotalDataWritten (0), TotalDataWritten (0),
TrueCryptMode (false), TrueCryptMode (false),
Pim (0) Pim (0),
EncryptionNotCompleted (false)
{ {
} }
@ -206,6 +209,7 @@ namespace VeraCrypt
VolumeDataOffset = layout->GetDataOffset (VolumeHostSize); VolumeDataOffset = layout->GetDataOffset (VolumeHostSize);
VolumeDataSize = layout->GetDataSize (VolumeHostSize); VolumeDataSize = layout->GetDataSize (VolumeHostSize);
EncryptedDataSize = header->GetEncryptedAreaLength();
Header = header; Header = header;
Layout = layout; Layout = layout;
@ -215,7 +219,11 @@ namespace VeraCrypt
if (layout->HasDriveHeader()) if (layout->HasDriveHeader())
{ {
if (header->GetEncryptedAreaLength() != header->GetVolumeDataSize()) 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(); uint64 partitionStartOffset = VolumeFile->GetPartitionDeviceStartOffset();
@ -223,6 +231,8 @@ namespace VeraCrypt
|| partitionStartOffset >= header->GetEncryptedAreaStart() + header->GetEncryptedAreaLength()) || partitionStartOffset >= header->GetEncryptedAreaStart() + header->GetEncryptedAreaLength())
throw PasswordIncorrect (SRC_POS); throw PasswordIncorrect (SRC_POS);
EncryptedDataSize -= partitionStartOffset - header->GetEncryptedAreaStart();
mode.SetSectorOffset (partitionStartOffset / ENCRYPTION_DATA_UNIT_SIZE); mode.SetSectorOffset (partitionStartOffset / ENCRYPTION_DATA_UNIT_SIZE);
} }
@ -313,7 +323,31 @@ namespace VeraCrypt
if (VolumeFile->ReadAt (buffer, hostOffset) != length) if (VolumeFile->ReadAt (buffer, hostOffset) != length)
throw MissingVolumeData (SRC_POS); 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; TotalDataRead += length;
} }

View File

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