private byte[] DecryptHeader(byte[] headerBytes, byte[] password) { Pbkdf2 pbkdf2; KeyValuePairList <HMAC, int> hmacs = new KeyValuePairList <HMAC, int>(); hmacs.Add(new HMACSHA512(), 1000); hmacs.Add(new HMACRIPEMD160(), 2000); hmacs.Add(new HMACWhirlpool(), 1000); foreach (KeyValuePair <HMAC, int> entry in hmacs) { HMAC hmac = entry.Key; int iterations = entry.Value; pbkdf2 = new Pbkdf2(hmac, password, Salt, iterations); byte[] key = pbkdf2.GetBytes(192); List <KeyValuePairList <SymmetricAlgorithm, byte[]> > algorithms = GetAlgorithms(key); foreach (KeyValuePairList <SymmetricAlgorithm, byte[]> algorithmChain in algorithms) { byte[] decrypt = (byte[])headerBytes.Clone(); // TrueCrypt 7.1a Source (Common\Crypto.c): // ---------------------------------------- // When encrypting/decrypting a buffer (typically a volume header) the sequential number // of the first XTS data unit in the buffer is always 0 and the start of the buffer is // always assumed to be aligned with the start of the data unit 0. decrypt = XTSHelper.XTSChainDecrypt(algorithmChain, 0, decrypt, 0, 448); string signature = ByteReader.ReadAnsiString(decrypt, 0, 4); ushort formatVersion = BigEndianConverter.ToUInt16(decrypt, 4); uint checksum256 = BigEndianConverter.ToUInt32(decrypt, 8); byte[] temp = ByteReader.ReadBytes(decrypt, 192, 256); uint computedChecksum = Utilities.CRC32.Compute(temp); if (signature == TrueCryptSignature && checksum256 == computedChecksum) { m_isValid = true; if (formatVersion == SupportedFormatVersion) { m_isSupported = true; } m_algorithmChain = algorithmChain; m_hmac = hmac; return(decrypt); } } } return(null); }
public override byte[] ReadSectors(long sectorIndex, int sectorCount) { CheckBoundaries(sectorIndex, sectorCount); long imageSectorIndex = sectorIndex + (long)m_header.MasterKeyScopeOffset / m_volume.BytesPerSector; byte[] sectors = m_volume.ReadSectors(imageSectorIndex, sectorCount); Parallel.For(0, sectorCount, delegate(int index){ int offset = index * m_volume.BytesPerSector; XTSHelper.XTSChainDecrypt(m_header.AlgorithmChain, (ulong)(imageSectorIndex + index), sectors, offset, m_volume.BytesPerSector, sectors, offset); }); return(sectors); }