diff options
Diffstat (limited to 'src/Volume/Volume.cpp')
-rw-r--r-- | src/Volume/Volume.cpp | 65 |
1 files changed, 47 insertions, 18 deletions
diff --git a/src/Volume/Volume.cpp b/src/Volume/Volume.cpp index d3ef2067..524f2395 100644 --- a/src/Volume/Volume.cpp +++ b/src/Volume/Volume.cpp @@ -24,12 +24,14 @@ 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) { } @@ -68,7 +70,7 @@ namespace VeraCrypt return EA->GetMode(); } - void Volume::Open (const VolumePath &volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection, shared_ptr <VolumePassword> protectionPassword, int protectionPim, shared_ptr <Pkcs5Kdf> protectionKdf, shared_ptr <KeyfileList> protectionKeyfiles, bool sharedAccessAllowed, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope) + void Volume::Open (const VolumePath &volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, shared_ptr <KeyfileList> keyfiles, bool emvSupportEnabled, VolumeProtection::Enum protection, shared_ptr <VolumePassword> protectionPassword, int protectionPim, shared_ptr <Pkcs5Kdf> protectionKdf, shared_ptr <KeyfileList> protectionKeyfiles, bool sharedAccessAllowed, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope) { make_shared_auto (File, file); @@ -99,18 +101,14 @@ namespace VeraCrypt throw; } - return Open (file, password, pim, kdf, truecryptMode, keyfiles, protection, protectionPassword, protectionPim, protectionKdf,protectionKeyfiles, volumeType, useBackupHeaders, partitionInSystemEncryptionScope); + return Open (file, password, pim, kdf, keyfiles, emvSupportEnabled, protection, protectionPassword, protectionPim, protectionKdf,protectionKeyfiles, volumeType, useBackupHeaders, partitionInSystemEncryptionScope); } - void Volume::Open (shared_ptr <File> volumeFile, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection, shared_ptr <VolumePassword> protectionPassword, int protectionPim, shared_ptr <Pkcs5Kdf> protectionKdf,shared_ptr <KeyfileList> protectionKeyfiles, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope) + void Volume::Open (shared_ptr <File> volumeFile, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, shared_ptr <KeyfileList> keyfiles, bool emvSupportEnabled, VolumeProtection::Enum protection, shared_ptr <VolumePassword> protectionPassword, int protectionPim, shared_ptr <Pkcs5Kdf> protectionKdf,shared_ptr <KeyfileList> protectionKeyfiles, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope) { if (!volumeFile) throw ParameterIncorrect (SRC_POS); - // TrueCrypt doesn't support SHA-256 - if (kdf && truecryptMode && (kdf->GetName() == L"HMAC-SHA-256")) - throw UnsupportedAlgoInTrueCryptMode (SRC_POS); - Protection = protection; VolumeFile = volumeFile; SystemEncryption = partitionInSystemEncryptionScope; @@ -118,7 +116,7 @@ namespace VeraCrypt try { VolumeHostSize = VolumeFile->Length(); - shared_ptr <VolumePassword> passwordKey = Keyfile::ApplyListToPassword (keyfiles, password); + shared_ptr <VolumePassword> passwordKey = Keyfile::ApplyListToPassword (keyfiles, password, emvSupportEnabled); bool skipLayoutV1Normal = false; @@ -187,11 +185,11 @@ namespace VeraCrypt shared_ptr <VolumeHeader> header = layout->GetHeader(); - if (header->Decrypt (headerBuffer, *passwordKey, pim, kdf, truecryptMode, layout->GetSupportedKeyDerivationFunctions(truecryptMode), layoutEncryptionAlgorithms, layoutEncryptionModes)) + if (header->Decrypt (headerBuffer, *passwordKey, pim, kdf, layout->GetSupportedKeyDerivationFunctions(), layoutEncryptionAlgorithms, layoutEncryptionModes)) { // Header decrypted - if (!truecryptMode && typeid (*layout) == typeid (VolumeLayoutV2Normal) && header->GetRequiredMinProgramVersion() < 0x10b) + if (typeid (*layout) == typeid (VolumeLayoutV2Normal) && header->GetRequiredMinProgramVersion() < 0x10b) { // VolumeLayoutV1Normal has been opened as VolumeLayoutV2Normal layout.reset (new VolumeLayoutV1Normal); @@ -199,13 +197,13 @@ namespace VeraCrypt layout->SetHeader (header); } - TrueCryptMode = truecryptMode; Pim = pim; Type = layout->GetType(); SectorSize = header->GetSectorSize(); VolumeDataOffset = layout->GetDataOffset (VolumeHostSize); VolumeDataSize = layout->GetDataSize (VolumeHostSize); + EncryptedDataSize = header->GetEncryptedAreaLength(); Header = header; Layout = layout; @@ -215,7 +213,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 +225,8 @@ namespace VeraCrypt || partitionStartOffset >= header->GetEncryptedAreaStart() + header->GetEncryptedAreaLength()) throw PasswordIncorrect (SRC_POS); + EncryptedDataSize -= partitionStartOffset - header->GetEncryptedAreaStart(); + mode.SetSectorOffset (partitionStartOffset / ENCRYPTION_DATA_UNIT_SIZE); } @@ -238,7 +242,8 @@ namespace VeraCrypt Volume protectedVolume; protectedVolume.Open (VolumeFile, - protectionPassword, protectionPim, protectionKdf, truecryptMode, protectionKeyfiles, + protectionPassword, protectionPim, protectionKdf, protectionKeyfiles, + emvSupportEnabled, VolumeProtection::ReadOnly, shared_ptr <VolumePassword> (), 0, shared_ptr <Pkcs5Kdf> (),shared_ptr <KeyfileList> (), VolumeType::Hidden, @@ -276,8 +281,8 @@ namespace VeraCrypt Buffer mbr (VolumeFile->GetDeviceSectorSize()); driveDevice.ReadAt (mbr, 0); - // Search for the string "VeraCrypt" or "TrueCrypt" - const char* bootSignature = truecryptMode? "TrueCrypt" : TC_APP_NAME; + // Search for the string "VeraCrypt" + const char* bootSignature = TC_APP_NAME; size_t nameLen = strlen (bootSignature); for (size_t i = 0; i < mbr.Size() - nameLen; ++i) { @@ -306,6 +311,7 @@ namespace VeraCrypt uint64 length = buffer.Size(); uint64 hostOffset = VolumeDataOffset + byteOffset; + size_t bufferOffset = 0; if (length % SectorSize != 0 || byteOffset % SectorSize != 0) throw ParameterIncorrect (SRC_POS); @@ -313,7 +319,30 @@ namespace VeraCrypt if (VolumeFile->ReadAt (buffer, hostOffset) != length) throw MissingVolumeData (SRC_POS); - EA->DecryptSectors (buffer, hostOffset / SectorSize, length / SectorSize, SectorSize); + // first sector can be unencrypted in some cases (e.g. windows repair) + // detect this case by looking for NTFS header + if (SystemEncryption && (hostOffset == 0) && ((BE64 (*(uint64 *) buffer.Get ())) == 0xEB52904E54465320ULL)) + { + bufferOffset = (size_t) SectorSize; + hostOffset += SectorSize; + length -= SectorSize; + } + + if (length) + { + if (EncryptionNotCompleted) + { + // if encryption is not complete, we decrypt only the encrypted sectors + if (hostOffset < EncryptedDataSize) + { + uint64 encryptedLength = VC_MIN (length, (EncryptedDataSize - hostOffset)); + + EA->DecryptSectors (buffer.GetRange (bufferOffset, encryptedLength), hostOffset / SectorSize, encryptedLength / SectorSize, SectorSize); + } + } + else + EA->DecryptSectors (buffer.GetRange (bufferOffset, length), hostOffset / SectorSize, length / SectorSize, SectorSize); + } TotalDataRead += length; } |