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; } }
void CompareOutput(IPadding Padding) { CSPPrng rng = new CSPPrng(); byte[] fill = new byte[16]; rng.GetBytes(fill); const int BLOCK = 16; for (int i = 0; i < BLOCK; i++) { byte[] data = new byte[BLOCK]; // fill with rand if (i > 0) { Array.Copy(fill, data, BLOCK - i); } // pad array Padding.AddPadding(data, i); // verify length int len = Padding.GetPaddingLength(data); if (len == 0 && i != 0) { throw new Exception("PaddingTest: Failed the padding value return check!"); } else if (i != 0 && len != BLOCK - i) { throw new Exception("PaddingTest: Failed the padding value return check!"); } // test offset method if (i > 0 && i < 15) { len = Padding.GetPaddingLength(data, i); if (len == 0 && i != 0) { throw new Exception("PaddingTest: Failed the padding value return check!"); } else if (i != 0 && len != BLOCK - i) { throw new Exception("PaddingTest: Failed the padding value return check!"); } } } rng.Dispose(); }
private void EncryptFile(string InputPath, string OutputPath, MemoryStream Header) { using (BinaryReader inputReader = new BinaryReader(new FileStream(InputPath, FileMode.Open, FileAccess.Read, FileShare.None))) { byte[] inputBuffer = new byte[this.BlockSize]; byte[] outputBuffer = new byte[this.BlockSize]; long bytesRead = 0; long bytesTotal = 0; using (BinaryWriter outputWriter = new BinaryWriter(new FileStream(OutputPath, FileMode.Create, FileAccess.Write, FileShare.None))) { // write message header outputWriter.Write(Header.ToArray()); while ((bytesRead = inputReader.Read(inputBuffer, 0, this.BlockSize)) == this.BlockSize) { this.Mode.Transform(inputBuffer, outputBuffer); outputWriter.Write(outputBuffer); bytesTotal += bytesRead; if (bytesTotal % this.ProgressInterval == 0) { CalculateProgress(bytesTotal); } } if (bytesRead > 0) { if (bytesRead < this.BlockSize) { Padding.AddPadding(inputBuffer, (int)bytesRead); } this.Mode.Transform(inputBuffer, outputBuffer); outputWriter.Write(outputBuffer); CalculateProgress(bytesTotal + bytesRead); } } } }