Пример #1
0
        private void ReadHeader(long volumeHeaderOffset)
        {
            long volumeHeaderSectorIndex = volumeHeaderOffset / m_volume.BytesPerSector;

            byte[] headerBytes = m_volume.ReadSector(volumeHeaderSectorIndex);
            m_header = new TrueCryptHeader(headerBytes, m_password);
        }
Пример #2
0
        /// <summary>
        /// Extend the partition and TrueCrypt volume
        /// </summary>
        public static TrueCryptResizeStatus ExtendVolume(Disk disk, byte[] password, long additionalNumberOfSectors)
        {
            Partition       partition = VolumeSelectionHelper.GetLastPartition(disk);
            TrueCryptVolume volume;

            try
            {
                volume = new TrueCryptVolume(partition, password);
            }
            catch (InvalidDataException)
            {
                return(TrueCryptResizeStatus.InvalidDisk);
            }
            catch (NotSupportedException)
            {
                return(TrueCryptResizeStatus.UnsupportedFormatVersion);
            }

            if (volume.IsHiddenVolume)
            {
                return(TrueCryptResizeStatus.HiddenVolume);
            }

            long availableBytes;

            if (partition is MBRPartition || partition is GPTPartition)
            {
                availableBytes = ExtendHelper.GetMaximumSizeToExtendPartition(partition);
            }
            else // Removable volume
            {
                availableBytes = additionalNumberOfSectors * volume.BytesPerSector;
            }

            TrueCryptHeader header = volume.Header;
            long            oldBackupHeaderOffset = (long)(header.MasterKeyScopeOffset + header.MasterKeyEncryptedAreaSize);
            long            newBackupHeaderOffset = (long)(header.MasterKeyScopeOffset + header.MasterKeyEncryptedAreaSize + (ulong)availableBytes);

            header.MasterKeyEncryptedAreaSize += (ulong)availableBytes;
            header.VolumeSize += (ulong)availableBytes;
            byte[] headerBytes = header.GetBytes(password);
            // Read backup header group from old end of the partition
            byte[] backupHeaderGroupBytes = partition.ReadSectors(oldBackupHeaderOffset / disk.BytesPerSector, TrueCryptVolume.VolumeHeaderGroupLength / disk.BytesPerSector);
            // Updated the backup header (using the stored salt)
            header.Salt = ByteReader.ReadBytes(backupHeaderGroupBytes, 0, 64);
            byte[] backupHeaderBytes = header.GetBytes(password);
            Array.Copy(backupHeaderBytes, 0, backupHeaderGroupBytes, 0, backupHeaderBytes.Length);

            if (partition is MBRPartition || partition is GPTPartition)
            {
                long availableSectors = availableBytes / disk.BytesPerSector;
                ExtendHelper.ExtendPartition((Partition)partition, availableSectors);
                // Reinitialize the partition
                partition = VolumeSelectionHelper.GetLastPartition(disk);
            }

            // Write backup header to the new end of the partition
            partition.WriteSectors(newBackupHeaderOffset / disk.BytesPerSector, backupHeaderGroupBytes);

            // Destroy the old backup header (to prevent decryption of the volume after the password has changed)
            byte[] temp = new byte[TrueCryptVolume.VolumeHeaderGroupLength];
            new Random().NextBytes(temp);
            partition.WriteSectors(oldBackupHeaderOffset / disk.BytesPerSector, temp);

            // Write an updated header
            partition.WriteSectors(0, headerBytes);

            return(TrueCryptResizeStatus.Success);
        }