Annotation of truecrypt/volume/volumeheader.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: #include "Platform/Time.h"
        !            10: #include "Crc32.h"
        !            11: #include "EncryptionModeXTS.h"
        !            12: #include "Pkcs5Kdf.h"
        !            13: #include "Pkcs5Kdf.h"
        !            14: #include "VolumeHeader.h"
        !            15: #include "VolumeException.h"
        !            16: 
        !            17: namespace TrueCrypt
        !            18: {
        !            19:        VolumeHeader::VolumeHeader (uint32 size)
        !            20:                : HeaderSize (size), EncryptedHeaderDataSize (size - EncryptedHeaderDataOffset)
        !            21:        {
        !            22:        }
        !            23: 
        !            24:        VolumeHeader::~VolumeHeader ()
        !            25:        {
        !            26:                VolumeKeyAreaCrc32 = 0;
        !            27:                VolumeCreationTime = 0;
        !            28:                HeaderCreationTime = 0;
        !            29:                mVolumeType = VolumeType::Unknown;
        !            30:                HiddenVolumeDataSize = 0;
        !            31:                VolumeDataSize = 0;
        !            32:                EncryptedAreaStart = 0;
        !            33:                EncryptedAreaLength = 0;
        !            34:        }
        !            35: 
        !            36:        void VolumeHeader::Create (const BufferPtr &headerBuffer, VolumeHeaderCreationOptions &options)
        !            37:        {
        !            38:                if (options.DataKey.Size() != options.EA->GetKeySize() * 2 || options.Salt.Size() != GetSaltSize())
        !            39:                        throw ParameterIncorrect (SRC_POS);
        !            40: 
        !            41:                headerBuffer.Zero();
        !            42: 
        !            43:                HeaderVersion = CurrentHeaderVersion;
        !            44:                RequiredMinProgramVersion = CurrentRequiredMinProgramVersion;
        !            45: 
        !            46:                DataAreaKey.Zero();
        !            47:                DataAreaKey.CopyFrom (options.DataKey);
        !            48: 
        !            49:                VolumeCreationTime = Time::GetCurrent();
        !            50:                HiddenVolumeDataSize = (options.Type == VolumeType::Hidden ? options.VolumeSize : 0);
        !            51:                VolumeDataSize = options.VolumeSize;
        !            52: 
        !            53:                EncryptedAreaStart = 0;
        !            54:                EncryptedAreaLength = options.VolumeSize;
        !            55: 
        !            56:                EA = options.EA;
        !            57:                shared_ptr <EncryptionMode> mode (new EncryptionModeXTS ());
        !            58:                EA->SetMode (mode);
        !            59: 
        !            60:                EncryptNew (headerBuffer, options.Salt, options.HeaderKey, options.Kdf);
        !            61:        }
        !            62: 
        !            63:        bool VolumeHeader::Decrypt (const ConstBufferPtr &encryptedData, const VolumePassword &password, const EncryptionAlgorithmList &encryptionAlgorithms, const EncryptionModeList &encryptionModes)
        !            64:        {
        !            65:                if (password.Size() < 1)
        !            66:                        throw PasswordEmpty (SRC_POS);
        !            67: 
        !            68:                ConstBufferPtr salt (encryptedData.GetRange (SaltOffset, SaltSize));
        !            69:                SecureBuffer header (EncryptedHeaderDataSize);
        !            70:                SecureBuffer headerKey (GetLargestSerializedKeySize());
        !            71: 
        !            72:                foreach (shared_ptr <Pkcs5Kdf> pkcs5, Pkcs5Kdf::GetAvailableAlgorithms())
        !            73:                {
        !            74:                        pkcs5->DeriveKey (headerKey, password, salt);
        !            75: 
        !            76:                        foreach (shared_ptr <EncryptionMode> mode, encryptionModes)
        !            77:                        {
        !            78:                                if (typeid (*mode) != typeid (EncryptionModeXTS))
        !            79:                                        mode->SetKey (headerKey.GetRange (0, mode->GetKeySize()));
        !            80: 
        !            81:                                foreach (shared_ptr <EncryptionAlgorithm> ea, encryptionAlgorithms)
        !            82:                                {
        !            83:                                        if (!ea->IsModeSupported (mode))
        !            84:                                                continue;
        !            85: 
        !            86:                                        if (typeid (*mode) == typeid (EncryptionModeXTS))
        !            87:                                        {
        !            88:                                                ea->SetKey (headerKey.GetRange (0, ea->GetKeySize()));
        !            89:                                                
        !            90:                                                mode = mode->GetNew();
        !            91:                                                mode->SetKey (headerKey.GetRange (ea->GetKeySize(), ea->GetKeySize()));
        !            92:                                        }
        !            93:                                        else
        !            94:                                        {
        !            95:                                                ea->SetKey (headerKey.GetRange (LegacyEncryptionModeKeyAreaSize, ea->GetKeySize()));
        !            96:                                        }
        !            97: 
        !            98:                                        ea->SetMode (mode);
        !            99: 
        !           100:                                        header.CopyFrom (encryptedData.GetRange (EncryptedHeaderDataOffset, EncryptedHeaderDataSize));
        !           101:                                        ea->Decrypt (header);
        !           102: 
        !           103:                                        if (Deserialize (header, ea, mode))
        !           104:                                        {
        !           105:                                                EA = ea;
        !           106:                                                Pkcs5 = pkcs5;
        !           107:                                                return true;
        !           108:                                        }
        !           109:                                }
        !           110:                        }
        !           111:                }
        !           112: 
        !           113:                return false;
        !           114:        }
        !           115: 
        !           116:        bool VolumeHeader::Deserialize (const ConstBufferPtr &header, shared_ptr <EncryptionAlgorithm> &ea, shared_ptr <EncryptionMode> &mode)
        !           117:        {
        !           118:                if (header.Size() != EncryptedHeaderDataSize)
        !           119:                        throw ParameterIncorrect (SRC_POS);
        !           120: 
        !           121:                if (header[0] != 'T' ||
        !           122:                        header[1] != 'R' ||
        !           123:                        header[2] != 'U' ||
        !           124:                        header[3] != 'E')
        !           125:                        return false;
        !           126: 
        !           127:                size_t offset = 4;
        !           128:                HeaderVersion = DeserializeEntry <uint16> (header, offset);
        !           129: 
        !           130:                if (HeaderVersion < MinAllowedHeaderVersion)
        !           131:                        return false;
        !           132: 
        !           133:                RequiredMinProgramVersion = DeserializeEntry <uint16> (header, offset);
        !           134:                
        !           135:                if (RequiredMinProgramVersion > Version::Number())
        !           136:                        throw HigherVersionRequired (SRC_POS);
        !           137: 
        !           138:                VolumeKeyAreaCrc32 = DeserializeEntry <uint32> (header, offset);
        !           139:                VolumeCreationTime = DeserializeEntry <uint64> (header, offset);
        !           140:                HeaderCreationTime = DeserializeEntry <uint64> (header, offset);
        !           141:                HiddenVolumeDataSize = DeserializeEntry <uint64> (header, offset);
        !           142:                mVolumeType = (HiddenVolumeDataSize != 0 ? VolumeType::Hidden : VolumeType::Normal);
        !           143:                VolumeDataSize = DeserializeEntry <uint64> (header, offset);
        !           144:                EncryptedAreaStart = DeserializeEntry <uint64> (header, offset);
        !           145:                EncryptedAreaLength = DeserializeEntry <uint64> (header, offset);
        !           146: 
        !           147:                offset = DataAreaKeyOffset;
        !           148: 
        !           149:                if (VolumeKeyAreaCrc32 != Crc32::ProcessBuffer (header.GetRange (offset, DataKeyAreaMaxSize)))
        !           150:                        return false;
        !           151: 
        !           152:                DataAreaKey.CopyFrom (header.GetRange (offset, DataKeyAreaMaxSize));
        !           153:                
        !           154:                ea = ea->GetNew();
        !           155:                mode = mode->GetNew();
        !           156:                
        !           157:                if (typeid (*mode) == typeid (EncryptionModeXTS))
        !           158:                {
        !           159:                        ea->SetKey (header.GetRange (offset, ea->GetKeySize()));
        !           160:                        mode->SetKey (header.GetRange (offset + ea->GetKeySize(), ea->GetKeySize()));
        !           161:                }
        !           162:                else
        !           163:                {
        !           164:                        mode->SetKey (header.GetRange (offset, mode->GetKeySize()));
        !           165:                        ea->SetKey (header.GetRange (offset + LegacyEncryptionModeKeyAreaSize, ea->GetKeySize()));
        !           166:                }
        !           167: 
        !           168:                ea->SetMode (mode);
        !           169: 
        !           170:                return true;
        !           171:        }
        !           172: 
        !           173:        template <typename T>
        !           174:        T VolumeHeader::DeserializeEntry (const ConstBufferPtr &header, size_t &offset) const
        !           175:        {
        !           176:                offset += sizeof (T);
        !           177: 
        !           178:                if (offset > header.Size())
        !           179:                        throw ParameterIncorrect (SRC_POS);
        !           180: 
        !           181:                return Endian::Big (*reinterpret_cast<const T *> (header.Get() + offset - sizeof (T)));
        !           182:        }
        !           183: 
        !           184:        void VolumeHeader::EncryptNew (const BufferPtr &newHeaderBuffer, const ConstBufferPtr &newSalt, const ConstBufferPtr &newHeaderKey, shared_ptr <Pkcs5Kdf> newPkcs5Kdf)
        !           185:        {
        !           186:                if (newHeaderBuffer.Size() != HeaderSize || newSalt.Size() != SaltSize)
        !           187:                        throw ParameterIncorrect (SRC_POS);
        !           188: 
        !           189:                shared_ptr <EncryptionMode> mode = EA->GetMode()->GetNew();
        !           190:                shared_ptr <EncryptionAlgorithm> ea = EA->GetNew();
        !           191: 
        !           192:                if (typeid (*mode) == typeid (EncryptionModeXTS))
        !           193:                {
        !           194:                        mode->SetKey (newHeaderKey.GetRange (EA->GetKeySize(), EA->GetKeySize()));
        !           195:                        ea->SetKey (newHeaderKey.GetRange (0, ea->GetKeySize()));
        !           196:                }
        !           197:                else
        !           198:                {
        !           199:                        mode->SetKey (newHeaderKey.GetRange (0, mode->GetKeySize()));
        !           200:                        ea->SetKey (newHeaderKey.GetRange (LegacyEncryptionModeKeyAreaSize, ea->GetKeySize()));
        !           201:                }
        !           202: 
        !           203:                ea->SetMode (mode);
        !           204: 
        !           205:                BufferPtr headerData = newHeaderBuffer.GetRange (EncryptedHeaderDataOffset, EncryptedHeaderDataSize);
        !           206: 
        !           207:                Serialize (headerData);
        !           208:                ea->Encrypt (headerData);
        !           209: 
        !           210:                Memory::Copy (newHeaderBuffer, newSalt, newSalt.Size());
        !           211: 
        !           212:                if (newPkcs5Kdf)
        !           213:                        Pkcs5 = newPkcs5Kdf;
        !           214:        }
        !           215: 
        !           216:        size_t VolumeHeader::GetLargestSerializedKeySize ()
        !           217:        {
        !           218:                size_t largestKey = EncryptionAlgorithm::GetLargestKeySize (EncryptionAlgorithm::GetAvailableAlgorithms());
        !           219:                
        !           220:                // XTS mode requires the same key size as the encryption algorithm.
        !           221:                // Legacy modes may require larger key than XTS.
        !           222:                if (LegacyEncryptionModeKeyAreaSize + largestKey > largestKey * 2)
        !           223:                        return LegacyEncryptionModeKeyAreaSize + largestKey;
        !           224: 
        !           225:                return largestKey * 2;
        !           226:        }
        !           227: 
        !           228:        void VolumeHeader::Serialize (const BufferPtr &header) const
        !           229:        {
        !           230:                if (header.Size() != EncryptedHeaderDataSize)
        !           231:                        throw ParameterIncorrect (SRC_POS);
        !           232: 
        !           233:                header.Zero();
        !           234: 
        !           235:                header[0] = 'T';
        !           236:                header[1] = 'R';
        !           237:                header[2] = 'U';
        !           238:                header[3] = 'E';
        !           239:                size_t offset = 4;
        !           240: 
        !           241:                header.GetRange (DataAreaKeyOffset, DataAreaKey.Size()).CopyFrom (DataAreaKey);
        !           242: 
        !           243:                SerializeEntry (HeaderVersion, header, offset);
        !           244:                SerializeEntry (RequiredMinProgramVersion, header, offset);
        !           245:                SerializeEntry (Crc32::ProcessBuffer (header.GetRange (DataAreaKeyOffset, DataKeyAreaMaxSize)), header, offset);
        !           246:                SerializeEntry (VolumeCreationTime, header, offset);
        !           247:                SerializeEntry (Time::GetCurrent(), header, offset);
        !           248:                SerializeEntry (HiddenVolumeDataSize, header, offset);
        !           249:                SerializeEntry (VolumeDataSize, header, offset);
        !           250:                SerializeEntry (EncryptedAreaStart, header, offset);
        !           251:                SerializeEntry (EncryptedAreaLength, header, offset);
        !           252: 
        !           253:        }
        !           254: 
        !           255:        template <typename T>
        !           256:        void VolumeHeader::SerializeEntry (const T &entry, const BufferPtr &header, size_t &offset) const
        !           257:        {
        !           258:                offset += sizeof (T);
        !           259: 
        !           260:                if (offset > header.Size())
        !           261:                        throw ParameterIncorrect (SRC_POS);
        !           262: 
        !           263:                *reinterpret_cast<T *> (header.Get() + offset - sizeof (T)) = Endian::Big (entry);
        !           264:        }
        !           265: }

unix.superglobalmegacorp.com

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