/// <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; }
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; } }
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; } }
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); } }
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; } }
private void BlockCipherArrayTest() { int counter = 0; while (counter < _dataSize) { _cipherEngine.Transform(_inputBuffer, 0, _outputBuffer, 0); counter += _blockSize; } }
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; } }
private byte[] SymmetricTransform(ICipherMode Cipher, byte[] Data) { byte[] ptext = new byte[Data.Length]; Cipher.Transform(Data, ptext); return(ptext); }
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); } }
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)); }
/// <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); }
/// <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); }
/// <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; } }
/// <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; }
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; }
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; }