Annotation of truecrypt/volume/volume.cpp, revision 1.1.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.