Annotation of truecrypt/volume/volumeheader.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: #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.