VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMounir IDRASSI <mounir.idrassi@idrix.fr>2018-06-10 22:12:32 (GMT)
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2018-06-10 22:14:53 (GMT)
commitd5dca62b044290475d9dd793e4abb58fbfe776d5 (patch)
tree7be77fd08807fe82682d9cb966418c89d0b8a9b8 /src
parent509c8288d01070a4e1ac0723313f3d6cd6f61a72 (diff)
downloadVeraCrypt-d5dca62b044290475d9dd793e4abb58fbfe776d5.zip
VeraCrypt-d5dca62b044290475d9dd793e4abb58fbfe776d5.tar.gz
Linux/MacOSX/FreeBSD: Support mounting partially encrypted system partitions/drivers in ReadOnly mode in order to allow troubleshooting in some cases.
Diffstat (limited to 'src')
-rw-r--r--src/Core/Unix/Linux/CoreLinux.cpp1
-rw-r--r--src/Volume/Volume.cpp40
-rw-r--r--src/Volume/Volume.h4
3 files changed, 42 insertions, 3 deletions
diff --git a/src/Core/Unix/Linux/CoreLinux.cpp b/src/Core/Unix/Linux/CoreLinux.cpp
index 0fa97f6..7f18fff 100644
--- a/src/Core/Unix/Linux/CoreLinux.cpp
+++ b/src/Core/Unix/Linux/CoreLinux.cpp
@@ -313,6 +313,7 @@ namespace VeraCrypt
if (options.NoKernelCrypto
|| !xts
|| algoNotSupported
+ || volume->IsEncryptionNotCompleted ()
|| volume->GetProtectionType() == VolumeProtection::HiddenVolumeReadOnly)
{
throw NotApplicable (SRC_POS);
diff --git a/src/Volume/Volume.cpp b/src/Volume/Volume.cpp
index d3ef206..d4d799d 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;
}
diff --git a/src/Volume/Volume.h b/src/Volume/Volume.h
index 311c65b..a743a16 100644
--- a/src/Volume/Volume.h
+++ b/src/Volume/Volume.h
@@ -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 &);