Beispiel #1
0
        /// <summary>
        /// Update the buffer
        /// </summary>
        ///
        /// <param name="Input">Input data</param>
        /// <param name="InOffset">Offset within Input array</param>
        /// <param name="Length">Amount of data to process in bytes</param>
        ///
        /// <exception cref="CryptoMacException">Thrown if an invalid Input size is chosen</exception>
        public void BlockUpdate(byte[] Input, int InOffset, int Length)
        {
            if ((InOffset + Length) > Input.Length)
            {
                throw new CryptoMacException("CMAC:BlockUpdate", "The Input buffer is too short!", new ArgumentOutOfRangeException());
            }

            int gapLen = _blockSize - _wrkOffset;

            if (Length > gapLen)
            {
                Buffer.BlockCopy(Input, InOffset, _wrkBuffer, _wrkOffset, gapLen);

                _cipherType.Transform(_wrkBuffer, 0, _msgCode, 0);

                _wrkOffset = 0;
                Length    -= gapLen;
                InOffset  += gapLen;

                while (Length > _blockSize)
                {
                    _cipherType.Transform(Input, InOffset, _msgCode, 0);

                    Length   -= _blockSize;
                    InOffset += _blockSize;
                }
            }

            Buffer.BlockCopy(Input, InOffset, _wrkBuffer, _wrkOffset, Length);

            _wrkOffset += Length;
        }
Beispiel #2
0
        private void ParallelCTR(ICipherMode Cipher, byte[] Input, int InOffset, byte[] Output, int OutOffset)
        {
            int  blkSize = Cipher.ParallelBlockSize;
            long inpSize = (Input.Length - InOffset);
            long alnSize = (inpSize / blkSize) * blkSize;
            long count   = 0;

            Cipher.IsParallel        = true;
            Cipher.ParallelBlockSize = blkSize;

            // parallel blocks
            while (count != alnSize)
            {
                Cipher.Transform(Input, InOffset, Output, OutOffset);
                InOffset  += blkSize;
                OutOffset += blkSize;
                count     += blkSize;
            }

            if (alnSize != inpSize)
            {
                int    cnkSize   = (int)(inpSize - alnSize);
                byte[] inpBuffer = new byte[cnkSize];
                Buffer.BlockCopy(Input, InOffset, inpBuffer, 0, cnkSize);
                byte[] outBuffer = new byte[cnkSize];
                Cipher.Transform(inpBuffer, outBuffer);
                Buffer.BlockCopy(outBuffer, 0, Output, OutOffset, cnkSize);
                count += cnkSize;
            }
        }
Beispiel #3
0
        private void BlockEncrypt(ICipherMode Cipher, IPadding Padding, byte[] Input, int InOffset, ref byte[] Output, int OutOffset)
        {
            int  blkSize = Cipher.BlockSize;
            long inpSize = (Input.Length - InOffset);
            long alnSize = inpSize - (inpSize % blkSize);
            long count   = 0;

            Cipher.IsParallel = false;

            while (count != alnSize)
            {
                Cipher.Transform(Input, InOffset, Output, OutOffset);
                InOffset  += blkSize;
                OutOffset += blkSize;
                count     += blkSize;
            }

            // partial
            if (alnSize != inpSize)
            {
                int    fnlSize   = (int)(inpSize - alnSize);
                byte[] inpBuffer = new byte[blkSize];
                Buffer.BlockCopy(Input, InOffset, inpBuffer, 0, fnlSize);
                Padding.AddPadding(inpBuffer, fnlSize);
                byte[] outBuffer = new byte[blkSize];
                Cipher.Transform(inpBuffer, 0, outBuffer, 0);
                if (Output.Length != OutOffset + blkSize)
                {
                    Array.Resize(ref Output, OutOffset + blkSize);
                }
                Buffer.BlockCopy(outBuffer, 0, Output, OutOffset, blkSize);
                count += blkSize;
            }
        }
Beispiel #4
0
        private void BlockDecrypt(ICipherMode Cipher, IPadding Padding, byte[] Input, int InOffset, ref byte[] Output, int OutOffset)
        {
            int  blkSize = Cipher.BlockSize;
            long inpSize = (Input.Length - InOffset);
            long alnSize = inpSize - blkSize;
            long count   = 0;

            Cipher.IsParallel = false;

            while (count != alnSize)
            {
                Cipher.Transform(Input, InOffset, Output, OutOffset);
                InOffset  += blkSize;
                OutOffset += blkSize;
                count     += blkSize;
            }

            // last block
            byte[] inpBuffer = new byte[blkSize];
            Buffer.BlockCopy(Input, InOffset, inpBuffer, 0, blkSize);
            byte[] outBuffer = new byte[blkSize];
            Cipher.Transform(inpBuffer, 0, outBuffer, 0);
            int fnlSize = blkSize - Padding.GetPaddingLength(outBuffer, 0);

            Buffer.BlockCopy(outBuffer, 0, Output, OutOffset, fnlSize);
            OutOffset += fnlSize;

            if (Output.Length != OutOffset)
            {
                Array.Resize(ref Output, OutOffset);
            }
        }
Beispiel #5
0
        private void BlockCTR(ICipherMode Cipher, byte[] Input, int InOffset, byte[] Output, int OutOffset)
        {
            int  blkSize = Cipher.BlockSize;
            long inpSize = (Input.Length - InOffset);
            long alnSize = inpSize - (inpSize % blkSize);
            long count   = 0;

            Cipher.IsParallel = false;

            while (count != alnSize)
            {
                Cipher.Transform(Input, InOffset, Output, OutOffset);
                InOffset  += blkSize;
                OutOffset += blkSize;
                count     += blkSize;
            }

            // partial
            if (alnSize != inpSize)
            {
                int    cnkSize   = (int)(inpSize - alnSize);
                byte[] inpBuffer = new byte[blkSize];
                Buffer.BlockCopy(Input, InOffset, inpBuffer, 0, cnkSize);
                byte[] outBuffer = new byte[blkSize];
                Cipher.Transform(inpBuffer, 0, outBuffer, 0);
                Buffer.BlockCopy(outBuffer, 0, Output, OutOffset, cnkSize);
                count += cnkSize;
            }
        }
Beispiel #6
0
        private void BlockCipherArrayTest()
        {
            int counter = 0;

            while (counter < _dataSize)
            {
                _cipherEngine.Transform(_inputBuffer, 0, _outputBuffer, 0);
                counter += _blockSize;
            }
        }
Beispiel #7
0
        private void Decrypt(byte[] Input, int InOffset, byte[] Output, int OutOffset, int Length)
        {
            // no padding, input lengths must align
            Length += InOffset;

            while (InOffset < Length)
            {
                m_cipherEngine.Transform(Input, InOffset, Output, OutOffset);
                InOffset  += m_blockSize;
                OutOffset += m_blockSize;
            }
        }
Beispiel #8
0
        private byte[] SymmetricTransform(ICipherMode Cipher, byte[] Data)
        {
            byte[] ptext = new byte[Data.Length];
            Cipher.Transform(Data, ptext);

            return(ptext);
        }
Beispiel #9
0
        private void ParallelDecrypt(ICipherMode Cipher, IPadding Padding, byte[] Input, int InOffset, byte[] Output, int OutOffset)
        {
            int  blkSize = Cipher.ParallelBlockSize;
            long inpSize = (Input.Length - InOffset);
            long alnSize = (inpSize / blkSize) * blkSize;
            long count   = 0;

            Cipher.IsParallel        = true;
            Cipher.ParallelBlockSize = blkSize;

            // parallel
            while (count != alnSize)
            {
                Cipher.Transform(Input, InOffset, Output, OutOffset);
                InOffset  += blkSize;
                OutOffset += blkSize;
                count     += blkSize;
            }

            if (alnSize != inpSize)
            {
                int cnkSize = (int)(inpSize - alnSize);
                BlockDecrypt(Cipher, Padding, Input, InOffset, ref Output, OutOffset);
            }
        }
Beispiel #10
0
        private string MonteCarloTest(ICipherMode Engine)
        {
            byte[] outBytes = new byte[Engine.BlockSize];
            byte[] inBytes  = new byte[Engine.BlockSize];

            for (int i = 0; i < 100; i++)
            {
                Engine.Transform(inBytes, outBytes);
                inBytes = (byte[])outBytes.Clone();
            }

            return(HexConverter.ToString(outBytes));
        }
Beispiel #11
0
        /// <summary>
        /// Uses Transform(in_data, out_data) method
        /// </summary>
        private byte[] Transform2(ICipherMode Cipher, byte[] Input, int BlockSize)
        {
            // slower, mem copy can be expensive on large data..
            int blocks = Input.Length / BlockSize;

            byte[] outData  = new byte[Input.Length];
            byte[] inBlock  = new byte[BlockSize];
            byte[] outBlock = new byte[BlockSize];

            for (int i = 0; i < blocks; i++)
            {
                Buffer.BlockCopy(Input, i * BlockSize, inBlock, 0, BlockSize);
                Cipher.Transform(inBlock, outBlock);
                Buffer.BlockCopy(outBlock, 0, outData, i * BlockSize, BlockSize);
            }

            if (blocks * BlockSize < Input.Length)
            {
                Cipher.Transform(Input, blocks * BlockSize, outData, blocks * BlockSize);
            }

            return(outData);
        }
Beispiel #12
0
        /// <summary>
        /// Uses Transform(in_data, in_offset, out_data, out_offset) method
        /// </summary>
        private byte[] Transform1(ICipherMode Cipher, byte[] Input, int BlockSize)
        {
            byte[] outData = new byte[Input.Length];
            int    blocks  = Input.Length / BlockSize;

            for (int i = 0; i < blocks; i++)
            {
                Cipher.Transform(Input, i * BlockSize, outData, i * BlockSize);
            }

            if (blocks * BlockSize < Input.Length)
            {
                // ctr tests only
                int    diff      = Input.Length - (blocks * BlockSize);
                byte[] inpBuffer = new byte[diff];
                int    offset    = Input.Length - diff;
                Buffer.BlockCopy(Input, offset, inpBuffer, 0, diff);
                byte[] outBuffer = new byte[diff];
                Cipher.Transform(inpBuffer, outBuffer);
                Buffer.BlockCopy(outBuffer, 0, outData, offset, diff);
            }

            return(outData);
        }
Beispiel #13
0
        /// <summary>
        /// Update the buffer
        /// </summary>
        ///
        /// <param name="Input">Input data</param>
        /// <param name="InOffset">Offset within Input array</param>
        /// <param name="Length">Amount of data to process in bytes</param>
        ///
        /// <exception cref="CryptoMacException">Thrown if an invalid Input size is chosen</exception>
        public void BlockUpdate(byte[] Input, int InOffset, int Length)
        {
            if ((InOffset + Length) > Input.Length)
            {
                throw new CryptoMacException("CMAC:BlockUpdate", "The Input buffer is too short!", new ArgumentOutOfRangeException());
            }

            if (m_wrkOffset == m_blockSize)
            {
                m_cipherMode.Transform(m_wrkBuffer, 0, m_msgCode, 0);
                m_wrkOffset = 0;
            }

            int diff = m_blockSize - m_wrkOffset;

            if (Length > diff)
            {
                Buffer.BlockCopy(Input, InOffset, m_wrkBuffer, m_wrkOffset, diff);
                m_cipherMode.Transform(m_wrkBuffer, 0, m_msgCode, 0);
                m_wrkOffset = 0;
                Length     -= diff;
                InOffset   += diff;

                while (Length > m_blockSize)
                {
                    m_cipherMode.Transform(Input, InOffset, m_msgCode, 0);
                    Length   -= m_blockSize;
                    InOffset += m_blockSize;
                }
            }

            if (Length > 0)
            {
                Buffer.BlockCopy(Input, InOffset, m_wrkBuffer, m_wrkOffset, Length);
                m_wrkOffset += Length;
            }
        }
Beispiel #14
0
        /// <summary>
        /// Transform an array with the symmetric cipher
        /// </summary>
        private byte[] SymmetricTransform(ICipherMode Cipher, byte[] Data)
        {
            byte[] ptext = new byte[Data.Length];
            Cipher.Transform(Data, ptext);

            return ptext;
        }
Beispiel #15
0
        private byte[] Transform2(ICipherMode Cipher, byte[] Data, int BlockSize)
        {
            // slower, mem copy can be expensive on large data..
            int blocks = Data.Length / BlockSize;
            byte[] outData = new byte[Data.Length];
            byte[] inBlock = new byte[BlockSize];
            byte[] outBlock = new byte[BlockSize];

            if (Cipher.Name == "CTR")
            {
                Cipher.Transform(Data, outData);
            }
            else
            {
                for (int i = 0; i < blocks; i++)
                {
                    Buffer.BlockCopy(Data, i * BlockSize, inBlock, 0, BlockSize);
                    Cipher.Transform(inBlock, outBlock);
                    Buffer.BlockCopy(outBlock, 0, outData, i * BlockSize, BlockSize);
                }

                if (blocks * BlockSize < Data.Length)
                    Cipher.Transform(Data, blocks * BlockSize, outData, blocks * BlockSize);
            }

            return outData;
        }
Beispiel #16
0
        private byte[] Transform1(ICipherMode Cipher, byte[] Data, int BlockSize)
        {
            // best way, use the offsets
            int blocks = Data.Length / BlockSize;
            byte[] outData = new byte[Data.Length];

            for (int i = 0; i < blocks; i++)
                Cipher.Transform(Data, i * BlockSize, outData, i * BlockSize);

            // last partial in CTR
            if (blocks * BlockSize < Data.Length)
                Cipher.Transform(Data, blocks * BlockSize, outData, blocks * BlockSize);

            return outData;
        }