--- truecrypt/boot/windows/bootencryptedio.cpp 2018/04/24 16:49:04 1.1 +++ truecrypt/boot/windows/bootencryptedio.cpp 2018/04/24 17:03:46 1.1.1.5 @@ -1,16 +1,16 @@ /* Copyright (c) 2008 TrueCrypt Foundation. All rights reserved. - Governed by the TrueCrypt License 2.4 the full text of which is contained + Governed by the TrueCrypt License 2.7 the full text of which is contained in the file License.txt included in TrueCrypt binary and source code distribution packages. */ #include "Crypto.h" #include "Platform.h" -#include "Bios.h" #include "BootConfig.h" #include "BootDebug.h" +#include "BootDefs.h" #include "BootDiskIo.h" #include "BootEncryptedIo.h" @@ -18,24 +18,54 @@ BiosResult ReadEncryptedSectors (uint16 destSegment, uint16 destOffset, byte drive, uint64 sector, uint16 sectorCount) { BiosResult result; - byte sectorBuf[TC_LB_SIZE]; + bool decrypt = true; - while (sectorCount-- > 0) + if (BootCryptoInfo->hiddenVolume) { - result = ReadSectors (sectorBuf, drive, sector, 1); - - if (result != BiosResultSuccess) - return result; + if (ReadWritePartiallyCoversEncryptedArea (sector, sectorCount)) + return BiosResultInvalidFunction; - if (drive == EncryptedVirtualPartition.Drive && sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector) + if (sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector) { - DecryptDataUnits (sectorBuf, §or, 1, BootCryptoInfo); + // Remap the request to the hidden volume + sector -= EncryptedVirtualPartition.StartSector; + sector += HiddenVolumeStartSector; } + else + decrypt = false; + } - CopyMemory (sectorBuf, destSegment, destOffset, sizeof (sectorBuf)); + result = ReadSectors (destSegment, destOffset, drive, sector, sectorCount); - ++sector; - destOffset += sizeof (sectorBuf); + if (result != BiosResultSuccess || !decrypt) + return result; + + if (BootCryptoInfo->hiddenVolume) + { + // Convert sector number to data unit number of the hidden volume + sector -= HiddenVolumeStartSector; + sector += HiddenVolumeStartUnitNo; + } + + if (drive == EncryptedVirtualPartition.Drive) + { + while (sectorCount-- > 0) + { + if (BootCryptoInfo->hiddenVolume + || (sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector)) + { + AcquireSectorBuffer(); + CopyMemory (destSegment, destOffset, SectorBuffer, TC_LB_SIZE); + + DecryptDataUnits (SectorBuffer, §or, 1, BootCryptoInfo); + + CopyMemory (SectorBuffer, destSegment, destOffset, TC_LB_SIZE); + ReleaseSectorBuffer(); + } + + ++sector; + destOffset += TC_LB_SIZE; + } } return result; @@ -45,25 +75,54 @@ BiosResult ReadEncryptedSectors (uint16 BiosResult WriteEncryptedSectors (uint16 sourceSegment, uint16 sourceOffset, byte drive, uint64 sector, uint16 sectorCount) { BiosResult result; - byte sectorBuf[TC_LB_SIZE]; + AcquireSectorBuffer(); + uint64 dataUnitNo; + uint64 writeOffset; + + dataUnitNo = sector; + writeOffset.HighPart = 0; + writeOffset.LowPart = 0; + + if (BootCryptoInfo->hiddenVolume) + { + if (ReadWritePartiallyCoversEncryptedArea (sector, sectorCount)) + return BiosResultInvalidFunction; + + // Remap the request to the hidden volume + writeOffset = HiddenVolumeStartSector; + writeOffset -= EncryptedVirtualPartition.StartSector; + dataUnitNo -= EncryptedVirtualPartition.StartSector; + dataUnitNo += HiddenVolumeStartUnitNo; + } while (sectorCount-- > 0) { - CopyMemory (sourceSegment, sourceOffset, sectorBuf, sizeof (sectorBuf)); + CopyMemory (sourceSegment, sourceOffset, SectorBuffer, TC_LB_SIZE); if (drive == EncryptedVirtualPartition.Drive && sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector) { - EncryptDataUnits (sectorBuf, §or, 1, BootCryptoInfo); + EncryptDataUnits (SectorBuffer, &dataUnitNo, 1, BootCryptoInfo); } - result = WriteSectors (sectorBuf, drive, sector, 1); + result = WriteSectors (SectorBuffer, drive, sector + writeOffset, 1); if (result != BiosResultSuccess) - return result; + break; ++sector; - sourceOffset += sizeof (sectorBuf); + ++dataUnitNo; + sourceOffset += TC_LB_SIZE; } + ReleaseSectorBuffer(); return result; } + + +static bool ReadWritePartiallyCoversEncryptedArea (const uint64 §or, uint16 sectorCount) +{ + uint64 readWriteEnd = sector + --sectorCount; + + return ((sector < EncryptedVirtualPartition.StartSector && readWriteEnd >= EncryptedVirtualPartition.StartSector) + || (sector >= EncryptedVirtualPartition.StartSector && readWriteEnd > EncryptedVirtualPartition.EndSector)); +}