From 3bef7915dd0083514c94100d790e82a992fe6b1a Mon Sep 17 00:00:00 2001 From: Uncled1023 Date: Mon, 10 Apr 2017 17:15:18 -0700 Subject: [PATCH] Adding some handling of block offsets for in place encryption/decryption --- Utilities/Utilities/Crypto.cs | 12 ++++++------ Utilities/Utilities/ResponseHelper.cs | 2 +- Utilities/Utilities/StreamHelper.cs | 15 ++++++++++++++- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Utilities/Utilities/Crypto.cs b/Utilities/Utilities/Crypto.cs index 32e5cfc..8820c95 100644 --- a/Utilities/Utilities/Crypto.cs +++ b/Utilities/Utilities/Crypto.cs @@ -209,7 +209,7 @@ namespace Teknik.Utilities // Process the stream and save the bytes to the output do { - int processedBytes = ProcessCipherBlock(cipher, input, chunkSize, output, cipherOffset, out bytesRead); + int processedBytes = ProcessCipherBlock(cipher, input, 0, chunkSize, output, cipherOffset, out bytesRead); cipherOffset += processedBytes; } while (bytesRead > 0); @@ -234,7 +234,7 @@ namespace Teknik.Utilities int bytesRead = 0; do { - processedBytes = ProcessCipherBlock(cipher, input, chunkSize, buffer, 0, out bytesRead); + processedBytes = ProcessCipherBlock(cipher, input, 0, chunkSize, buffer, 0, out bytesRead); if (processedBytes > 0) { // We have bytes, lets write them to the file @@ -268,17 +268,17 @@ namespace Teknik.Utilities return cipher; } - public static int ProcessCipherBlock(IBufferedCipher cipher, Stream input, int chunkSize, byte[] output, int outputOffset, out int bytesRead) + public static int ProcessCipherBlock(IBufferedCipher cipher, Stream input, int inputOffset, int chunkSize, byte[] output, int outputOffset, out int bytesRead) { // Initialize buffer - byte[] buffer = new byte[chunkSize]; + byte[] buffer = new byte[chunkSize + inputOffset]; // Read the next block of data - bytesRead = input.Read(buffer, 0, chunkSize); + bytesRead = input.Read(buffer, 0, chunkSize + inputOffset); if (bytesRead > 0) { // process the cipher for the read block and add it to the output - return cipher.ProcessBytes(buffer, 0, bytesRead, output, outputOffset); + return cipher.ProcessBytes(buffer, inputOffset, bytesRead - inputOffset, output, outputOffset); } return 0; diff --git a/Utilities/Utilities/ResponseHelper.cs b/Utilities/Utilities/ResponseHelper.cs index f9a8016..dcf2ec8 100644 --- a/Utilities/Utilities/ResponseHelper.cs +++ b/Utilities/Utilities/ResponseHelper.cs @@ -100,7 +100,7 @@ namespace Teknik.Utilities { bytesToRead = bytesRemaining; } - processedBytes = AES.ProcessCipherBlock(cipher, stream, bytesToRead, buffer, 0, out bytesRead); + processedBytes = AES.ProcessCipherBlock(cipher, stream, 0, bytesToRead, buffer, 0, out bytesRead); if (processedBytes > 0) { response.OutputStream.Write(buffer, 0, processedBytes); diff --git a/Utilities/Utilities/StreamHelper.cs b/Utilities/Utilities/StreamHelper.cs index e5559f1..bfb69ca 100644 --- a/Utilities/Utilities/StreamHelper.cs +++ b/Utilities/Utilities/StreamHelper.cs @@ -24,9 +24,22 @@ namespace Teknik.Utilities if (_Inner != null && CanRead) { int bytesRead = 0; + long startPosition = _Inner.Position; + int blockSize = _Cipher.GetBlockSize(); + long blockOffset = (startPosition % blockSize); + + // Determine if we are at the start of a block, or not + if (blockOffset != 0) + { + // We are not a multiple of the block size, so let's backup to get the current block + _Inner.Seek(startPosition - blockOffset, SeekOrigin.Begin); + } // Process the cipher - int processed = AES.ProcessCipherBlock(_Cipher, _Inner, count, buffer, offset, out bytesRead); + int processed = AES.ProcessCipherBlock(_Cipher, _Inner, 0, count + (int)blockOffset, buffer, offset, out bytesRead); + + // Adjust bytes read by the block offset + bytesRead -= (int)blockOffset; if (processed < bytesRead) {