Exemple #1
0
		private byte[] ComputeHeaderHmac(byte[] pbHeader, byte[] pbKey)
		{
			byte[] pbHeaderHmac;
			byte[] pbBlockKey = HmacBlockStream.GetHmacKey64(
				pbKey, ulong.MaxValue);
			using(HMACSHA256 h = new HMACSHA256(pbBlockKey))
			{
				pbHeaderHmac = h.ComputeHash(pbHeader);
			}
			MemUtil.ZeroByteArray(pbBlockKey);

			return pbHeaderHmac;
		}
Exemple #2
0
        private void WriteSafeBlock()
        {
            byte[] pbBlockIndex = MemUtil.UInt64ToBytes(m_uBlockIndex);

            int cbBlockSize = m_iBufferPos;

            byte[] pbBlockSize = MemUtil.Int32ToBytes(cbBlockSize);

            byte[] pbBlockHmac;
            byte[] pbBlockKey = GetHmacKey64(m_pbKey, m_uBlockIndex);
            using (HMACSHA256 h = new HMACSHA256(pbBlockKey))
            {
                h.TransformBlock(pbBlockIndex, 0, pbBlockIndex.Length,
                                 pbBlockIndex, 0);
                h.TransformBlock(pbBlockSize, 0, pbBlockSize.Length,
                                 pbBlockSize, 0);

                if (cbBlockSize > 0)
                {
                    h.TransformBlock(m_pbBuffer, 0, cbBlockSize, m_pbBuffer, 0);
                }

                h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);

                pbBlockHmac = h.Hash;
            }
            MemUtil.ZeroByteArray(pbBlockKey);

            MemUtil.Write(m_sBase, pbBlockHmac);
            // MemUtil.Write(m_sBase, pbBlockIndex); // Implicit
            MemUtil.Write(m_sBase, pbBlockSize);
            if (cbBlockSize > 0)
            {
                m_sBase.Write(m_pbBuffer, 0, cbBlockSize);
            }

            ++m_uBlockIndex;
            m_iBufferPos = 0;
        }
Exemple #3
0
        private bool ReadSafeBlock()
        {
            if (m_bEos)
            {
                return(false);                   // End of stream reached already
            }
            byte[] pbStoredHmac = MemUtil.Read(m_sBase, 32);
            if ((pbStoredHmac == null) || (pbStoredHmac.Length != 32))
            {
                throw new EndOfStreamException(KLRes.FileCorrupted + " " +
                                               KLRes.FileIncomplete);
            }

            // Block index is implicit: it's used in the HMAC computation,
            // but does not need to be stored
            // byte[] pbBlockIndex = MemUtil.Read(m_sBase, 8);
            // if((pbBlockIndex == null) || (pbBlockIndex.Length != 8))
            //	throw new EndOfStreamException();
            // ulong uBlockIndex = MemUtil.BytesToUInt64(pbBlockIndex);
            // if((uBlockIndex != m_uBlockIndex) && m_bVerify)
            //	throw new InvalidDataException();
            byte[] pbBlockIndex = MemUtil.UInt64ToBytes(m_uBlockIndex);

            byte[] pbBlockSize = MemUtil.Read(m_sBase, 4);
            if ((pbBlockSize == null) || (pbBlockSize.Length != 4))
            {
                throw new EndOfStreamException(KLRes.FileCorrupted + " " +
                                               KLRes.FileIncomplete);
            }
            int nBlockSize = MemUtil.BytesToInt32(pbBlockSize);

            if (nBlockSize < 0)
            {
                throw new InvalidDataException(KLRes.FileCorrupted);
            }

            m_iBufferPos = 0;

            m_pbBuffer = MemUtil.Read(m_sBase, nBlockSize);
            if ((m_pbBuffer == null) || ((m_pbBuffer.Length != nBlockSize) && m_bVerify))
            {
                throw new EndOfStreamException(KLRes.FileCorrupted + " " +
                                               KLRes.FileIncompleteExpc);
            }

            if (m_bVerify)
            {
                byte[] pbCmpHmac;
                byte[] pbBlockKey = GetHmacKey64(m_pbKey, m_uBlockIndex);
                using (HMACSHA256 h = new HMACSHA256(pbBlockKey))
                {
                    h.TransformBlock(pbBlockIndex, 0, pbBlockIndex.Length,
                                     pbBlockIndex, 0);
                    h.TransformBlock(pbBlockSize, 0, pbBlockSize.Length,
                                     pbBlockSize, 0);

                    if (m_pbBuffer.Length > 0)
                    {
                        h.TransformBlock(m_pbBuffer, 0, m_pbBuffer.Length,
                                         m_pbBuffer, 0);
                    }

                    h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);

                    pbCmpHmac = h.Hash;
                }
                MemUtil.ZeroByteArray(pbBlockKey);

                if (!MemUtil.ArraysEqual(pbCmpHmac, pbStoredHmac))
                {
                    throw new InvalidDataException(KLRes.FileCorrupted);
                }
            }

            ++m_uBlockIndex;

            if (nBlockSize == 0)
            {
                m_bEos = true;
                return(false);                // No further data available
            }
            return(true);
        }
Exemple #4
0
        /// <summary>
        /// Create a cryptographic key of length <paramref name="cbOut" />
        /// (in bytes) from <paramref name="pbIn" />.
        /// </summary>
        public static byte[] ResizeKey(byte[] pbIn, int iInOffset,
                                       int cbIn, int cbOut)
        {
            if (pbIn == null)
            {
                throw new ArgumentNullException("pbIn");
            }
            if (cbOut < 0)
            {
                throw new ArgumentOutOfRangeException("cbOut");
            }

            if (cbOut == 0)
            {
                return(MemUtil.EmptyByteArray);
            }

            byte[] pbHash;
            if (cbOut <= 32)
            {
                pbHash = HashSha256(pbIn, iInOffset, cbIn);
            }
            else
            {
                using (SHA512Managed h = new SHA512Managed())
                {
                    pbHash = h.ComputeHash(pbIn, iInOffset, cbIn);
                }
            }

            if (cbOut == pbHash.Length)
            {
                return(pbHash);
            }

            byte[] pbRet = new byte[cbOut];
            if (cbOut < pbHash.Length)
            {
                Array.Copy(pbHash, pbRet, cbOut);
            }
            else
            {
                int   iPos = 0;
                ulong r    = 0;
                while (iPos < cbOut)
                {
                    Debug.Assert(pbHash.Length == 64);
                    using (HMACSHA256 h = new HMACSHA256(pbHash))
                    {
                        byte[] pbR    = MemUtil.UInt64ToBytes(r);
                        byte[] pbPart = h.ComputeHash(pbR);

                        int cbCopy = Math.Min(cbOut - iPos, pbPart.Length);
                        Debug.Assert(cbCopy > 0);

                        Array.Copy(pbPart, 0, pbRet, iPos, cbCopy);
                        iPos += cbCopy;
                        ++r;

                        MemUtil.ZeroByteArray(pbPart);
                    }
                }
                Debug.Assert(iPos == cbOut);
            }

#if DEBUG
            byte[] pbZero = new byte[pbHash.Length];
            Debug.Assert(!MemUtil.ArraysEqual(pbHash, pbZero));
#endif
            MemUtil.ZeroByteArray(pbHash);
            return(pbRet);
        }