Exemplo n.º 1
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;
        }
Exemplo n.º 2
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);
        }