Annotation of truecrypt/volume/volume.cpp, revision 1.1

1.1     ! root        1: /*
        !             2:  Copyright (c) 2008 TrueCrypt Foundation. All rights reserved.
        !             3: 
        !             4:  Governed by the TrueCrypt License 2.4 the full text of which is contained
        !             5:  in the file License.txt included in TrueCrypt binary and source code
        !             6:  distribution packages.
        !             7: */
        !             8: 
        !             9: #ifndef TC_WINDOWS
        !            10: #include <errno.h>
        !            11: #endif
        !            12: #include "EncryptionModeLRW.h"
        !            13: #include "EncryptionModeXTS.h"
        !            14: #include "Volume.h"
        !            15: #include "VolumeHeader.h"
        !            16: #include "VolumeLayout.h"
        !            17: 
        !            18: namespace TrueCrypt
        !            19: {
        !            20:        Volume::Volume ()
        !            21:                : HiddenVolumeProtectionTriggered (false),
        !            22:                VolumeDataSize (0),
        !            23:                TotalDataRead (0),
        !            24:                TotalDataWritten (0)
        !            25:        {
        !            26:        }
        !            27: 
        !            28:        Volume::~Volume ()
        !            29:        {
        !            30:        }
        !            31: 
        !            32:        void Volume::CheckProtectedRange (uint64 writeHostOffset, uint64 writeLength)
        !            33:        {
        !            34:                uint64 writeHostEndOffset = writeHostOffset + writeLength - 1;
        !            35: 
        !            36:                if ((writeHostOffset < ProtectedRangeStart) ? (writeHostEndOffset >= ProtectedRangeStart) : (writeHostOffset <= ProtectedRangeEnd - 1))
        !            37:                {
        !            38:                        HiddenVolumeProtectionTriggered = true;
        !            39:                        throw VolumeProtected (SRC_POS);
        !            40:                }
        !            41:        }
        !            42: 
        !            43:        void Volume::Close ()
        !            44:        {
        !            45:                if (VolumeFile.get() == nullptr)
        !            46:                        throw NotInitialized (SRC_POS);
        !            47:                
        !            48:                VolumeFile.reset();
        !            49:        }
        !            50: 
        !            51:        shared_ptr <EncryptionAlgorithm> Volume::GetEncryptionAlgorithm () const
        !            52:        {
        !            53:                if_debug (ValidateState ());
        !            54:                return EA;
        !            55:        }
        !            56: 
        !            57:        shared_ptr <EncryptionMode> Volume::GetEncryptionMode () const
        !            58:        {
        !            59:                if_debug (ValidateState ());
        !            60:                return EA->GetMode();
        !            61:        }
        !            62: 
        !            63:        void Volume::Open (const VolumePath &volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection, shared_ptr <VolumePassword> protectionPassword, shared_ptr <KeyfileList> protectionKeyfiles, bool sharedAccessAllowed, VolumeType::Enum volumeType)
        !            64:        {
        !            65:                make_shared_auto (File, file);
        !            66: 
        !            67:                File::FileOpenFlags flags = (preserveTimestamps ? File::PreserveTimestamps : File::FlagsNone);
        !            68: 
        !            69:                try
        !            70:                {
        !            71:                        if (protection == VolumeProtection::ReadOnly)
        !            72:                                file->Open (volumePath, File::OpenRead, File::ShareRead, flags);
        !            73:                        else
        !            74:                                file->Open (volumePath, File::OpenReadWrite, File::ShareNone, flags);
        !            75:                }
        !            76:                catch (SystemException &e)
        !            77:                {
        !            78:                        if (e.GetErrorCode() == 
        !            79: #ifdef TC_WINDOWS
        !            80:                                ERROR_SHARING_VIOLATION)
        !            81: #else
        !            82:                                EAGAIN)
        !            83: #endif
        !            84:                        {
        !            85:                                if (!sharedAccessAllowed)
        !            86:                                        throw VolumeHostInUse (SRC_POS);
        !            87: 
        !            88:                                file->Open (volumePath, protection == VolumeProtection::ReadOnly ? File::OpenRead : File::OpenReadWrite, File::ShareReadWriteIgnoreLock, flags);
        !            89:                        }
        !            90:                        else
        !            91:                                throw;
        !            92:                }
        !            93: 
        !            94:                return Open (file, password, keyfiles, protection, protectionPassword, protectionKeyfiles, volumeType);
        !            95:        }
        !            96: 
        !            97:        void Volume::Open (shared_ptr <File> volumeFile, shared_ptr <VolumePassword> password, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection, shared_ptr <VolumePassword> protectionPassword, shared_ptr <KeyfileList> protectionKeyfiles, VolumeType::Enum volumeType)
        !            98:        {
        !            99:                if (!volumeFile)
        !           100:                        throw ParameterIncorrect (SRC_POS);
        !           101: 
        !           102:                Protection = protection;
        !           103:                VolumeFile = volumeFile;
        !           104: 
        !           105:                try
        !           106:                {
        !           107:                        VolumeHostSize = VolumeFile->Length();
        !           108:                        shared_ptr <VolumePassword> passwordKey = Keyfile::ApplyListToPassword (keyfiles, password);
        !           109: 
        !           110:                        // Test volume layouts
        !           111:                        foreach (shared_ptr <VolumeLayout> layout, VolumeLayout::GetAvailableLayouts (volumeType))
        !           112:                        {
        !           113:                                if (layout->GetHeaderOffset() >= 0)
        !           114:                                        VolumeFile->SeekAt (layout->GetHeaderOffset());
        !           115:                                else
        !           116:                                        VolumeFile->SeekEnd (layout->GetHeaderOffset());
        !           117: 
        !           118:                                SecureBuffer headerBuffer (layout->GetHeaderSize());
        !           119: 
        !           120:                                if (VolumeFile->Read (headerBuffer) != layout->GetHeaderSize())
        !           121:                                        throw MissingVolumeData (SRC_POS);
        !           122: 
        !           123:                                shared_ptr <VolumeHeader> header = layout->GetHeader();
        !           124: 
        !           125:                                if (header->Decrypt (headerBuffer, *passwordKey, layout->GetSupportedEncryptionAlgorithms(), layout->GetSupportedEncryptionModes ()))
        !           126:                                {
        !           127:                                        // Header decrypted
        !           128:                                        Type = layout->GetType();
        !           129:                                        SectorSize = header->GetSectorSize();
        !           130:                                        VolumeDataOffset = layout->GetDataOffset (VolumeHostSize);
        !           131:                                        VolumeDataSize = layout->GetDataSize (VolumeHostSize);
        !           132: 
        !           133:                                        Header = header;
        !           134:                                        Layout = layout;
        !           135:                                        EA = header->GetEncryptionAlgorithm();
        !           136:                                        EncryptionMode &mode = *EA->GetMode();
        !           137: 
        !           138:                                        if (typeid (mode) == typeid (EncryptionModeLRW))
        !           139:                                                mode.SetSectorOffset (VolumeDataOffset / SectorSize);
        !           140: 
        !           141:                                        // Volume protection
        !           142:                                        if (Protection == VolumeProtection::HiddenVolumeReadOnly)
        !           143:                                        {
        !           144:                                                if (Type == VolumeType::Hidden)
        !           145:                                                        Protection = VolumeProtection::ReadOnly;
        !           146:                                                else
        !           147:                                                {
        !           148:                                                        try
        !           149:                                                        {
        !           150:                                                                Volume protectedVolume;
        !           151: 
        !           152:                                                                protectedVolume.Open (VolumeFile,
        !           153:                                                                        protectionPassword, protectionKeyfiles,
        !           154:                                                                        VolumeProtection::ReadOnly,
        !           155:                                                                        shared_ptr <VolumePassword> (), shared_ptr <KeyfileList> (),
        !           156:                                                                        VolumeType::Hidden);
        !           157: 
        !           158:                                                                if (protectedVolume.GetType() != VolumeType::Hidden)
        !           159:                                                                        ParameterIncorrect (SRC_POS);
        !           160: 
        !           161:                                                                ProtectedRangeStart = protectedVolume.VolumeDataOffset;
        !           162:                                                                ProtectedRangeEnd = protectedVolume.VolumeDataOffset + protectedVolume.VolumeDataSize + protectedVolume.Layout->GetHeaderSize();
        !           163:                                                        }
        !           164:                                                        catch (PasswordException&)
        !           165:                                                        {
        !           166:                                                                if (protectionKeyfiles && !protectionKeyfiles->empty())
        !           167:                                                                        throw ProtectionPasswordKeyfilesIncorrect (SRC_POS);
        !           168:                                                                throw ProtectionPasswordIncorrect (SRC_POS);
        !           169:                                                        }
        !           170:                                                }
        !           171:                                        }
        !           172:                                        return;
        !           173:                                }
        !           174:                        }
        !           175:                        if (keyfiles && !keyfiles->empty())
        !           176:                                throw PasswordKeyfilesIncorrect (SRC_POS);
        !           177:                        throw PasswordIncorrect (SRC_POS);
        !           178:                }
        !           179:                catch (...)
        !           180:                {
        !           181:                        Close();
        !           182:                        throw;
        !           183:                }
        !           184:        }
        !           185: 
        !           186:        void Volume::ReadSectors (const BufferPtr &buffer, uint64 byteOffset)
        !           187:        {
        !           188:                if_debug (ValidateState ());
        !           189: 
        !           190:                uint64 length = buffer.Size();
        !           191:                uint64 hostOffset = VolumeDataOffset + byteOffset;
        !           192: 
        !           193:                if (length % SectorSize != 0 || byteOffset % SectorSize != 0)
        !           194:                        throw ParameterIncorrect (SRC_POS);
        !           195: 
        !           196:                if (VolumeFile->ReadAt (buffer, hostOffset) != length)
        !           197:                        throw MissingVolumeData (SRC_POS);
        !           198: 
        !           199:                EA->DecryptSectors (buffer, hostOffset / SectorSize, length / SectorSize, SectorSize);
        !           200: 
        !           201:                TotalDataRead += length;
        !           202:        }
        !           203: 
        !           204:        void Volume::ReEncryptHeader (const ConstBufferPtr &newSalt, const ConstBufferPtr &newHeaderKey, shared_ptr <Pkcs5Kdf> newPkcs5Kdf)
        !           205:        {
        !           206:                if_debug (ValidateState ());
        !           207:                
        !           208:                if (Protection == VolumeProtection::ReadOnly)
        !           209:                        throw VolumeReadOnly (SRC_POS);
        !           210: 
        !           211:                SecureBuffer newHeaderBuffer (Layout->GetHeaderSize());
        !           212:                
        !           213:                Header->EncryptNew (newHeaderBuffer, newSalt, newHeaderKey, newPkcs5Kdf);
        !           214: 
        !           215:                if (Layout->GetHeaderOffset() >= 0)
        !           216:                        VolumeFile->SeekAt (Layout->GetHeaderOffset());
        !           217:                else
        !           218:                        VolumeFile->SeekEnd (Layout->GetHeaderOffset());
        !           219: 
        !           220:                VolumeFile->Write (newHeaderBuffer);
        !           221:        }
        !           222: 
        !           223:        void Volume::ValidateState () const
        !           224:        {
        !           225:                if (VolumeFile.get() == nullptr)
        !           226:                        throw NotInitialized (SRC_POS);
        !           227:        }
        !           228: 
        !           229:        void Volume::WriteSectors (const ConstBufferPtr &buffer, uint64 byteOffset)
        !           230:        {
        !           231:                if_debug (ValidateState ());
        !           232: 
        !           233:                uint64 length = buffer.Size();
        !           234:                uint64 hostOffset = VolumeDataOffset + byteOffset;
        !           235: 
        !           236:                if (length % SectorSize != 0
        !           237:                        || byteOffset % SectorSize != 0
        !           238:                        || byteOffset + length > VolumeDataSize)
        !           239:                        throw ParameterIncorrect (SRC_POS);
        !           240: 
        !           241:                if (Protection == VolumeProtection::ReadOnly)
        !           242:                        throw VolumeReadOnly (SRC_POS);
        !           243: 
        !           244:                if (HiddenVolumeProtectionTriggered)
        !           245:                        throw VolumeProtected (SRC_POS);
        !           246: 
        !           247:                if (Protection == VolumeProtection::HiddenVolumeReadOnly)
        !           248:                        CheckProtectedRange (hostOffset, length);
        !           249: 
        !           250:                SecureBuffer encBuf (buffer.Size());
        !           251:                encBuf.CopyFrom (buffer);
        !           252: 
        !           253:                EA->EncryptSectors (encBuf, hostOffset / SectorSize, length / SectorSize, SectorSize);
        !           254:                VolumeFile->WriteAt (encBuf, hostOffset);
        !           255: 
        !           256:                TotalDataWritten += length;
        !           257:        }
        !           258: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.