Inheritance: ICryptoTransform, IDisposable
	// Transform an input block into an output block.
	public static int TransformBlock(CryptoAPITransform transform,
									 byte[] inputBuffer, int inputOffset,
							         int inputCount, byte[] outputBuffer,
							         int outputOffset)
			{
				int blockSize = transform.blockSize;
				byte[] iv = transform.iv;
				IntPtr state = transform.state;
				int offset = outputOffset;
				int index;

				// Process all of the blocks in the input.
				while(inputCount >= blockSize)
				{
					// XOR the plaintext with the IV.
					for(index = blockSize - 1; index >= 0; --index)
					{
						iv[index] ^= inputBuffer[inputOffset + index];
					}

					// Encrypt the IV to get the ciphertext and the next IV.
					CryptoMethods.Encrypt(state, iv, 0, iv, 0);
					Array.Copy(iv, 0, outputBuffer, offset, blockSize);

					// Advance to the next block.
					inputOffset += blockSize;
					inputCount -= blockSize;
					offset += blockSize;
				}

				// Finished.
				return offset - outputOffset;
			}
Beispiel #2
0
        // Transform an input block into an output block.
        public static int TransformBlock(CryptoAPITransform transform,
                                         byte[] inputBuffer, int inputOffset,
                                         int inputCount, byte[] outputBuffer,
                                         int outputOffset)
        {
            int blockSize = transform.blockSize;

            byte[] iv     = transform.iv;
            IntPtr state  = transform.state;
            int    offset = outputOffset;
            int    index;

            // Process all of the blocks in the input.
            while (inputCount >= blockSize)
            {
                // XOR the plaintext with the IV.
                for (index = blockSize - 1; index >= 0; --index)
                {
                    iv[index] ^= inputBuffer[inputOffset + index];
                }

                // Encrypt the IV to get the ciphertext and the next IV.
                CryptoMethods.Encrypt(state, iv, 0, iv, 0);
                Array.Copy(iv, 0, outputBuffer, offset, blockSize);

                // Advance to the next block.
                inputOffset += blockSize;
                inputCount  -= blockSize;
                offset      += blockSize;
            }

            // Finished.
            return(offset - outputOffset);
        }
Beispiel #3
0
        // Transform an input block into an output block.
        public static int TransformBlock(CryptoAPITransform transform,
                                         byte[] inputBuffer, int inputOffset,
                                         int inputCount, byte[] outputBuffer,
                                         int outputOffset)
        {
            int blockSize = transform.blockSize;

            byte[] iv     = transform.iv;
            IntPtr state  = transform.state;
            int    offset = outputOffset;

            byte[] tempBuffer = transform.tempBuffer;
            int    tempSize   = transform.tempSize;
            int    index;

            // Process all of the data in the input.  We need to keep
            // the last two blocks for the finalization process.
            while (inputCount >= blockSize)
            {
                // If the temporary buffer is full, then flush a block
                // through the cipher in CBC mode.
                if (tempSize > blockSize)
                {
                    // Decrypt the ciphertext block and XOR with the IV.
                    CryptoMethods.Decrypt(state, tempBuffer, blockSize,
                                          tempBuffer, 0);
                    for (index = blockSize - 1; index >= 0; --index)
                    {
                        tempBuffer[index] ^= iv[index];
                    }

                    // Copy the original ciphertext to the IV.
                    Array.Copy(tempBuffer, blockSize, iv, 0, blockSize);

                    // Copy the plaintext into place.
                    Array.Copy(tempBuffer, 0, outputBuffer,
                               offset, blockSize);

                    // Advance to the next output block.
                    offset += blockSize;

                    // Shift the second block down to the first position.
                    Array.Copy(tempBuffer, blockSize * 2,
                               tempBuffer, blockSize, blockSize);
                    tempSize -= blockSize;
                }

                // Copy the next block into the temporary buffer.
                Array.Copy(inputBuffer, inputOffset,
                           tempBuffer, tempSize + blockSize, blockSize);
                inputOffset += blockSize;
                inputCount  -= blockSize;
                tempSize    += blockSize;
            }
            transform.tempSize = tempSize;

            // Finished.
            return(offset - outputOffset);
        }
	// Initialize a "CryptoAPITransform" object for CFB decryption.
	public static void Initialize(CryptoAPITransform transform)
			{
				// Initialize the CFB queue with the IV.
				transform.tempBuffer = new byte [transform.blockSize * 2];
				Array.Copy(transform.iv, 0, transform.tempBuffer,
						   transform.feedbackBlockSize, transform.blockSize);
				transform.tempSize = transform.feedbackBlockSize;
			}
Beispiel #5
0
 // Initialize a "CryptoAPITransform" object for OFB encryption.
 public static void Initialize(CryptoAPITransform transform)
 {
     // Initialize the OFB queue with the IV.
     transform.tempBuffer = new byte [transform.blockSize * 2];
     Array.Copy(transform.iv, 0, transform.tempBuffer,
                transform.feedbackBlockSize, transform.blockSize);
     transform.tempSize = transform.feedbackBlockSize;
 }
Beispiel #6
0
        // Transform an input block into an output block.
        public static int TransformBlock(CryptoAPITransform transform,
                                         byte[] inputBuffer, int inputOffset,
                                         int inputCount, byte[] outputBuffer,
                                         int outputOffset)
        {
            int blockSize = transform.blockSize;

            byte[] iv    = transform.iv;
            IntPtr state = transform.state;

            byte[] tempBuffer = transform.tempBuffer;
            int    offset     = outputOffset;
            int    index;
            bool   needPadding = (transform.padding != PaddingMode.None);

            // Process a left-over block from last time.
            if (transform.tempSize > 0 && inputCount > 0)
            {
                // Decrypt the ciphertext to get the plaintext.
                CryptoMethods.Decrypt(state, tempBuffer, 0,
                                      outputBuffer, offset);

                // Advance to the next block and clear the temporary block.
                offset            += blockSize;
                transform.tempSize = 0;
                for (index = blockSize - 1; index >= 0; --index)
                {
                    tempBuffer[index] = (byte)0x00;
                }
            }

            // Process all of the blocks in the input, minus one.
            // If we don't need padding, then process all of the blocks.
            while ((needPadding && inputCount > blockSize) ||
                   (!needPadding && inputCount >= blockSize))
            {
                // Decrypt the ciphertext to get the plaintext.
                CryptoMethods.Decrypt(state, inputBuffer, inputOffset,
                                      outputBuffer, offset);

                // Advance to the next block.
                inputOffset += blockSize;
                inputCount  -= blockSize;
                offset      += blockSize;
            }

            // Save the last block for next time.
            if (needPadding && inputCount > 0)
            {
                Array.Copy(inputBuffer, inputOffset,
                           tempBuffer, 0, inputCount);
                transform.tempSize = inputCount;
            }

            // Finished.
            return(offset - outputOffset);
        }
	// Transform an input block into an output block.
	public static int TransformBlock(CryptoAPITransform transform,
									 byte[] inputBuffer, int inputOffset,
							         int inputCount, byte[] outputBuffer,
							         int outputOffset)
			{
				int blockSize = transform.blockSize;
				byte[] iv = transform.iv;
				IntPtr state = transform.state;
				int offset = outputOffset;
				byte[] tempBuffer = transform.tempBuffer;
				int tempSize = transform.tempSize;
				int index;

				// Process all of the data in the input.  We need to keep
				// the last two blocks for the finalization process.
				while(inputCount >= blockSize)
				{
					// If the temporary buffer is full, then flush a block
					// through the cipher in CBC mode.
					if(tempSize > blockSize)
					{
						// Decrypt the ciphertext block and XOR with the IV.
						CryptoMethods.Decrypt(state, tempBuffer, blockSize,
											  tempBuffer, 0);
						for(index = blockSize - 1; index >= 0; --index)
						{
							tempBuffer[index] ^= iv[index];
						}

						// Copy the original ciphertext to the IV.
						Array.Copy(tempBuffer, blockSize, iv, 0, blockSize);

						// Copy the plaintext into place.
						Array.Copy(tempBuffer, 0, outputBuffer,
								   offset, blockSize);

						// Advance to the next output block.
						offset += blockSize;

						// Shift the second block down to the first position.
						Array.Copy(tempBuffer, blockSize * 2,
								   tempBuffer, blockSize, blockSize);
						tempSize -= blockSize;
					}

					// Copy the next block into the temporary buffer.
					Array.Copy(inputBuffer, inputOffset,
							   tempBuffer, tempSize + blockSize, blockSize);
					inputOffset += blockSize;
					inputCount -= blockSize;
					tempSize += blockSize;
				}
				transform.tempSize = tempSize;

				// Finished.
				return offset - outputOffset;
			}
	// Transform the final input block.
	public static byte[] TransformFinalBlock(CryptoAPITransform transform,
										     byte[] inputBuffer,
									  		 int inputOffset,
									  		 int inputCount)
			{
				byte[] outputBuffer = new byte [inputCount];
				TransformBlock(transform, inputBuffer, inputOffset,
							   inputCount, outputBuffer, 0);
				return outputBuffer;
			}
Beispiel #9
0
 // Transform the final input block.
 public static byte[] TransformFinalBlock(CryptoAPITransform transform,
                                          byte[] inputBuffer,
                                          int inputOffset,
                                          int inputCount)
 {
     byte[] outputBuffer = new byte [inputCount];
     TransformBlock(transform, inputBuffer, inputOffset,
                    inputCount, outputBuffer, 0);
     return(outputBuffer);
 }
	// Transform an input block into an output block.
	public static int TransformBlock(CryptoAPITransform transform,
									 byte[] inputBuffer, int inputOffset,
							         int inputCount, byte[] outputBuffer,
							         int outputOffset)
			{
				int blockSize = transform.blockSize;
				byte[] iv = transform.iv;
				IntPtr state = transform.state;
				byte[] tempBuffer = transform.tempBuffer;
				int offset = outputOffset;
				int index;
				bool needPadding = (transform.padding != PaddingMode.None);

				// Process a left-over block from last time.
				if(transform.tempSize > 0 && inputCount > 0)
				{
					// Decrypt the ciphertext to get the plaintext.
					CryptoMethods.Decrypt(state, tempBuffer, 0,
										  outputBuffer, offset);

					// Advance to the next block and clear the temporary block.
					offset += blockSize;
					transform.tempSize = 0;
					for(index = blockSize - 1; index >= 0; --index)
					{
						tempBuffer[index] = (byte)0x00;
					}
				}

				// Process all of the blocks in the input, minus one.
				// If we don't need padding, then process all of the blocks.
				while((needPadding && inputCount > blockSize) ||
				      (!needPadding && inputCount >= blockSize))
				{
					// Decrypt the ciphertext to get the plaintext.
					CryptoMethods.Decrypt(state, inputBuffer, inputOffset,
										  outputBuffer, offset);

					// Advance to the next block.
					inputOffset += blockSize;
					inputCount -= blockSize;
					offset += blockSize;
				}

				// Save the last block for next time.
				if(needPadding && inputCount > 0)
				{
					Array.Copy(inputBuffer, inputOffset,
							   tempBuffer, 0, inputCount);
					transform.tempSize = inputCount;
				}

				// Finished.
				return offset - outputOffset;
			}
Beispiel #11
0
        // Transform an input block into an output block.
        public static int TransformBlock(CryptoAPITransform transform,
                                         byte[] inputBuffer, int inputOffset,
                                         int inputCount, byte[] outputBuffer,
                                         int outputOffset)
        {
            int blockSize    = transform.blockSize;
            int feedbackSize = transform.feedbackBlockSize;

            byte[] iv     = transform.iv;
            IntPtr state  = transform.state;
            int    offset = outputOffset;

            byte[] tempBuffer = transform.tempBuffer;
            int    tempSize   = transform.tempSize;

            // Process all of the bytes in the input.
            while (inputCount > 0)
            {
                // Encrypt the queue if we need more keystream data.
                if (tempSize >= feedbackSize)
                {
                    CryptoMethods.Encrypt(state, tempBuffer,
                                          feedbackSize, tempBuffer, 0);
                    tempSize = 0;
                }

                // XOR the plaintext byte with the next keystream byte.
                outputBuffer[offset++] =
                    (byte)(tempBuffer[tempSize] ^
                           inputBuffer[inputOffset++]);
                --inputCount;

                // Feed the keystream byte back into the queue.
                tempBuffer[tempSize + blockSize] = tempBuffer[tempSize];
                ++tempSize;
            }
            transform.tempSize = tempSize;

            // Finished.
            return(offset - outputOffset);
        }
	// Transform an input block into an output block.
	public static int TransformBlock(CryptoAPITransform transform,
									 byte[] inputBuffer, int inputOffset,
							         int inputCount, byte[] outputBuffer,
							         int outputOffset)
			{
				int blockSize = transform.blockSize;
				IntPtr state = transform.state;
				int offset = outputOffset;

				// Process all of the blocks in the input.
				while(inputCount >= blockSize)
				{
					CryptoMethods.Encrypt(state, inputBuffer, inputOffset,
										  outputBuffer, offset);
					inputOffset += blockSize;
					inputCount -= blockSize;
					offset += blockSize;
				}

				// Finished.
				return offset - outputOffset;
			}
Beispiel #13
0
        // Transform an input block into an output block.
        public static int TransformBlock(CryptoAPITransform transform,
                                         byte[] inputBuffer, int inputOffset,
                                         int inputCount, byte[] outputBuffer,
                                         int outputOffset)
        {
            int    blockSize = transform.blockSize;
            IntPtr state     = transform.state;
            int    offset    = outputOffset;

            // Process all of the blocks in the input.
            while (inputCount >= blockSize)
            {
                CryptoMethods.Encrypt(state, inputBuffer, inputOffset,
                                      outputBuffer, offset);
                inputOffset += blockSize;
                inputCount  -= blockSize;
                offset      += blockSize;
            }

            // Finished.
            return(offset - outputOffset);
        }
	// Transform an input block into an output block.
	public static int TransformBlock(CryptoAPITransform transform,
									 byte[] inputBuffer, int inputOffset,
							         int inputCount, byte[] outputBuffer,
							         int outputOffset)
			{
				int blockSize = transform.blockSize;
				int feedbackSize = transform.feedbackBlockSize;
				byte[] iv = transform.iv;
				IntPtr state = transform.state;
				int offset = outputOffset;
				byte[] tempBuffer = transform.tempBuffer;
				int tempSize = transform.tempSize;

				// Process all of the bytes in the input.
				while(inputCount > 0)
				{
					// Encrypt the queue if we need more keystream data.
					if(tempSize >= feedbackSize)
					{
						CryptoMethods.Encrypt(state, tempBuffer,
											  feedbackSize, tempBuffer, 0);
						tempSize = 0;
					}

					// Feed the ciphertext byte back into the queue.
					tempBuffer[tempSize + blockSize] =
						inputBuffer[inputOffset];

					// XOR the plaintext byte with the next keystream byte.
					outputBuffer[offset++] =
						(byte)(tempBuffer[tempSize++] ^
							   inputBuffer[inputOffset++]);
					--inputCount;
				}
				transform.tempSize = tempSize;

				// Finished.
				return offset - outputOffset;
			}
	// Transform an input block into an output block.
	public static int TransformBlock(CryptoAPITransform transform,
									 byte[] inputBuffer, int inputOffset,
							         int inputCount, byte[] outputBuffer,
							         int outputOffset)
			{
				int blockSize = transform.blockSize;
				byte[] iv = transform.iv;
				IntPtr state = transform.state;
				byte[] tempBuffer = transform.tempBuffer;
				int offset = outputOffset;
				int index;

				// Process a left-over block from last time.
				if(transform.tempSize > 0 && inputCount > 0)
				{
					// Decrypt the ciphertext to get the plaintext
					// xor'ed with the IV.
					CryptoMethods.Decrypt(state, tempBuffer, blockSize,
										  tempBuffer, 0);

					// XOR the IV with the temporary buffer to get plaintext.
					for(index = blockSize - 1; index >= 0; --index)
					{
						outputBuffer[offset + index] =
							(byte)(iv[index] ^ tempBuffer[index]);
					}

					// Copy the original ciphertext to the IV.
					Array.Copy(tempBuffer, blockSize, iv, 0, blockSize);

					// Advance to the next block and clear the temporary block.
					offset += blockSize;
					transform.tempSize = 0;
					for(index = 2 * blockSize - 1; index >= blockSize; --index)
					{
						tempBuffer[index] = (byte)0x00;
					}
				}

				// Process all of the blocks in the input, minus one.
				while(inputCount > blockSize)
				{
					// Decrypt the ciphertext to get the plaintext
					// xor'ed with the IV.
					CryptoMethods.Decrypt(state, inputBuffer, inputOffset,
										  tempBuffer, 0);

					// XOR the IV with the temporary buffer to get plaintext.
					for(index = blockSize - 1; index >= 0; --index)
					{
						outputBuffer[offset + index] =
							(byte)(iv[index] ^ tempBuffer[index]);
					}

					// Copy the original ciphertext to the IV.
					Array.Copy(inputBuffer, inputOffset, iv, 0, blockSize);

					// Advance to the next block.
					inputOffset += blockSize;
					inputCount -= blockSize;
					offset += blockSize;
				}

				// Save the last block for next time.
				if(inputCount > 0)
				{
					Array.Copy(inputBuffer, inputOffset,
							   tempBuffer, blockSize, inputCount);
					transform.tempSize = inputCount;
				}

				// Clear the temporary buffer to protect sensitive data.
				for(index = blockSize - 1; index >= 0; --index)
				{
					tempBuffer[index] = (byte)0x00;
				}

				// Finished.
				return offset - outputOffset;
			}
	// Transform the final input block.
	public static byte[] TransformFinalBlock(CryptoAPITransform transform,
										     byte[] inputBuffer,
									  		 int inputOffset,
									  		 int inputCount)
			{
				int blockSize = transform.blockSize;
				byte[] iv = transform.iv;
				IntPtr state = transform.state;
				int offset = 0;
				int size, pad, index;
				byte[] outputBuffer;

				// Allocate space for the final block.
				if(transform.padding == PaddingMode.PKCS7)
				{
					size = inputCount + blockSize - (inputCount % blockSize);
				}
				else
				{
					size = inputCount;
					if((size % blockSize) != 0)
					{
						size += blockSize - (inputCount % blockSize);
					}
				}
				outputBuffer = new byte [size];

				// Process full blocks in the input.
				while(inputCount >= blockSize)
				{
					// XOR the plaintext with the IV.
					for(index = blockSize - 1; index >= 0; --index)
					{
						iv[index] ^= inputBuffer[inputOffset + index];
					}

					// Encrypt the IV to get the ciphertext and the next IV.
					CryptoMethods.Encrypt(state, iv, 0, iv, 0);
					Array.Copy(iv, 0, outputBuffer, offset, blockSize);

					// Advance to the next block.
					inputOffset += blockSize;
					inputCount -= blockSize;
					offset += blockSize;
				}

				// Format and encrypt the final partial block.
				if(transform.padding == PaddingMode.PKCS7)
				{
					// Pad the block according to PKCS #7 and XOR with the IV.
					for(index = 0; index < inputCount; ++index)
					{
						iv[index] ^= inputBuffer[inputOffset + index];
					}
					pad = blockSize - (inputCount % blockSize);
					while(index < blockSize)
					{
						iv[index] ^= (byte)pad;
						++index;
					}

					// Encrypt the IV to get the ciphertext and the next IV.
					CryptoMethods.Encrypt(state, iv, 0, iv, 0);
					Array.Copy(iv, 0, outputBuffer, offset, blockSize);
				}
				else if(inputCount > 0)
				{
					// Pad the block with zero bytes and XOR with the IV.
					// The zero padding is implicit.
					for(index = 0; index < inputCount; ++index)
					{
						iv[index] ^= inputBuffer[inputOffset + index];
					}

					// Encrypt the IV to get the ciphertext and the next IV.
					CryptoMethods.Encrypt(state, iv, 0, iv, 0);
					Array.Copy(iv, 0, outputBuffer, offset, blockSize);
				}

				// Finished.
				return outputBuffer;
			}
Beispiel #17
0
        // Transform the final input block.
        public static byte[] TransformFinalBlock(CryptoAPITransform transform,
                                                 byte[] inputBuffer,
                                                 int inputOffset,
                                                 int inputCount)
        {
            int blockSize = transform.blockSize;

            byte[] iv = transform.iv;
            IntPtr state = transform.state;
            int    offset = 0;
            int    size, pad, index;

            byte[] outputBuffer;

            // Allocate space for the final block.
            if (transform.padding == PaddingMode.PKCS7)
            {
                size = inputCount + blockSize - (inputCount % blockSize);
            }
            else
            {
                size = inputCount;
                if ((size % blockSize) != 0)
                {
                    size += blockSize - (inputCount % blockSize);
                }
            }
            outputBuffer = new byte [size];

            // Process full blocks in the input.
            while (inputCount >= blockSize)
            {
                // XOR the plaintext with the IV.
                for (index = blockSize - 1; index >= 0; --index)
                {
                    iv[index] ^= inputBuffer[inputOffset + index];
                }

                // Encrypt the IV to get the ciphertext and the next IV.
                CryptoMethods.Encrypt(state, iv, 0, iv, 0);
                Array.Copy(iv, 0, outputBuffer, offset, blockSize);

                // Advance to the next block.
                inputOffset += blockSize;
                inputCount  -= blockSize;
                offset      += blockSize;
            }

            // Format and encrypt the final partial block.
            if (transform.padding == PaddingMode.PKCS7)
            {
                // Pad the block according to PKCS #7 and XOR with the IV.
                for (index = 0; index < inputCount; ++index)
                {
                    iv[index] ^= inputBuffer[inputOffset + index];
                }
                pad = blockSize - (inputCount % blockSize);
                while (index < blockSize)
                {
                    iv[index] ^= (byte)pad;
                    ++index;
                }

                // Encrypt the IV to get the ciphertext and the next IV.
                CryptoMethods.Encrypt(state, iv, 0, iv, 0);
                Array.Copy(iv, 0, outputBuffer, offset, blockSize);
            }
            else if (inputCount > 0)
            {
                // Pad the block with zero bytes and XOR with the IV.
                // The zero padding is implicit.
                for (index = 0; index < inputCount; ++index)
                {
                    iv[index] ^= inputBuffer[inputOffset + index];
                }

                // Encrypt the IV to get the ciphertext and the next IV.
                CryptoMethods.Encrypt(state, iv, 0, iv, 0);
                Array.Copy(iv, 0, outputBuffer, offset, blockSize);
            }

            // Finished.
            return(outputBuffer);
        }
Beispiel #18
0
        // Transform an input block into an output block.
        public static int TransformBlock(CryptoAPITransform transform,
                                         byte[] inputBuffer, int inputOffset,
                                         int inputCount, byte[] outputBuffer,
                                         int outputOffset)
        {
            int blockSize = transform.blockSize;

            byte[] iv    = transform.iv;
            IntPtr state = transform.state;

            byte[] tempBuffer = transform.tempBuffer;
            int    offset     = outputOffset;
            int    index;

            // Process a left-over block from last time.
            if (transform.tempSize > 0 && inputCount > 0)
            {
                // Decrypt the ciphertext to get the plaintext
                // xor'ed with the IV.
                CryptoMethods.Decrypt(state, tempBuffer, blockSize,
                                      tempBuffer, 0);

                // XOR the IV with the temporary buffer to get plaintext.
                for (index = blockSize - 1; index >= 0; --index)
                {
                    outputBuffer[offset + index] =
                        (byte)(iv[index] ^ tempBuffer[index]);
                }

                // Copy the original ciphertext to the IV.
                Array.Copy(tempBuffer, blockSize, iv, 0, blockSize);

                // Advance to the next block and clear the temporary block.
                offset            += blockSize;
                transform.tempSize = 0;
                for (index = 2 * blockSize - 1; index >= blockSize; --index)
                {
                    tempBuffer[index] = (byte)0x00;
                }
            }

            // Process all of the blocks in the input, minus one.
            while (inputCount > blockSize)
            {
                // Decrypt the ciphertext to get the plaintext
                // xor'ed with the IV.
                CryptoMethods.Decrypt(state, inputBuffer, inputOffset,
                                      tempBuffer, 0);

                // XOR the IV with the temporary buffer to get plaintext.
                for (index = blockSize - 1; index >= 0; --index)
                {
                    outputBuffer[offset + index] =
                        (byte)(iv[index] ^ tempBuffer[index]);
                }

                // Copy the original ciphertext to the IV.
                Array.Copy(inputBuffer, inputOffset, iv, 0, blockSize);

                // Advance to the next block.
                inputOffset += blockSize;
                inputCount  -= blockSize;
                offset      += blockSize;
            }

            // Save the last block for next time.
            if (inputCount > 0)
            {
                Array.Copy(inputBuffer, inputOffset,
                           tempBuffer, blockSize, inputCount);
                transform.tempSize = inputCount;
            }

            // Clear the temporary buffer to protect sensitive data.
            for (index = blockSize - 1; index >= 0; --index)
            {
                tempBuffer[index] = (byte)0x00;
            }

            // Finished.
            return(offset - outputOffset);
        }
	// Transform the final input block.
	public static byte[] TransformFinalBlock(CryptoAPITransform transform,
										     byte[] inputBuffer,
									  		 int inputOffset,
									  		 int inputCount)
			{
				int blockSize = transform.blockSize;
				IntPtr state = transform.state;
				byte[] tempBuffer = transform.tempBuffer;
				byte[] outputBuffer;
				int offset, index, pad;

				// Allocate a temporary output buffer.
				outputBuffer = new byte [inputCount + blockSize];

				// Push the remaining bytes through the decryptor.  The
				// final block will end up in "transform.tempBuffer".
				offset = TransformBlock(transform, inputBuffer, inputOffset,
										inputCount, outputBuffer, 0);

				// Decrypt the final block in "tempBuffer".
				if(transform.tempSize > 0)
				{
					// Decrypt the ciphertext to get the plaintext.
					CryptoMethods.Decrypt(state, tempBuffer, 0,
										  tempBuffer, 0);

					// Remove padding.
					if(transform.padding == PaddingMode.PKCS7)
					{
						// Use PKCS #7 padding.
						pad = tempBuffer[blockSize - 1];
						if(pad == 0 || pad > blockSize)
						{
							pad = blockSize;
						}
						Array.Copy(tempBuffer, 0, outputBuffer,
								   offset, blockSize - pad);
						offset += blockSize - pad;
						pad = 0;
					}
					else if(transform.padding == PaddingMode.Zeros)
					{
						// Strip zeroes from the end of the block.
						index = blockSize;
						while(index > 0 && tempBuffer[index - 1] == 0)
						{
							--index;
						}
						Array.Copy(tempBuffer, 0, outputBuffer,
								   offset, index);
						offset += index;
					}
					else
					{
						// No padding, so return the whole block.
						Array.Copy(tempBuffer, 0, outputBuffer,
								   offset, blockSize);
						offset += blockSize;
					}
				}

				// Reduce the output buffer size to the final length.
				if(offset != outputBuffer.Length)
				{
					byte[] newout = new byte [offset];
					if(offset != 0)
					{
						Array.Copy(outputBuffer, 0, newout, 0, offset);
					}
					Array.Clear(outputBuffer, 0, outputBuffer.Length);
					outputBuffer = newout;
				}

				// Finished.
				return outputBuffer;
			}
Beispiel #20
0
        // Transform the final input block.
        public static byte[] TransformFinalBlock(CryptoAPITransform transform,
                                                 byte[] inputBuffer,
                                                 int inputOffset,
                                                 int inputCount)
        {
            int    blockSize = transform.blockSize;
            IntPtr state = transform.state;
            int    offset = 0;
            int    size, index, pad;

            byte[] outputBuffer;

            // Allocate space for the final block.
            if (transform.padding == PaddingMode.PKCS7)
            {
                size = inputCount + blockSize - (inputCount % blockSize);
            }
            else
            {
                size = inputCount;
                if ((size % blockSize) != 0)
                {
                    size += blockSize - (inputCount % blockSize);
                }
            }
            outputBuffer = new byte [size];

            // Process full blocks in the input.
            while (inputCount >= blockSize)
            {
                CryptoMethods.Encrypt(state, inputBuffer, inputOffset,
                                      outputBuffer, offset);
                inputOffset += blockSize;
                inputCount  -= blockSize;
                offset      += blockSize;
            }

            // Format and encrypt the final partial block.
            if (transform.padding == PaddingMode.PKCS7)
            {
                // Pad the block according to PKCS #7.
                for (index = 0; index < inputCount; ++index)
                {
                    outputBuffer[offset + index] =
                        inputBuffer[inputOffset + index];
                }
                pad = blockSize - (inputCount % blockSize);
                while (index < blockSize)
                {
                    outputBuffer[offset + index] = (byte)pad;
                    ++index;
                }

                // Encrypt the block.
                CryptoMethods.Encrypt(state, outputBuffer,
                                      offset + index - blockSize,
                                      outputBuffer,
                                      offset + index - blockSize);
            }
            else if (inputCount > 0)
            {
                // Pad the block with zero bytes.
                for (index = 0; index < inputCount; ++index)
                {
                    outputBuffer[offset + index] =
                        inputBuffer[inputOffset + index];
                }
                while (index < blockSize)
                {
                    outputBuffer[offset + index] = (byte)0x00;
                    ++index;
                }

                // Encrypt the block.
                CryptoMethods.Encrypt(state, outputBuffer,
                                      offset + index - blockSize,
                                      outputBuffer,
                                      offset + index - blockSize);
            }

            // Finished.
            return(outputBuffer);
        }
	// Initialize a "CryptoAPITransform" object for ECB decryption.
	public static void Initialize(CryptoAPITransform transform)
			{
				transform.tempBuffer = new byte [transform.blockSize * 2];
				transform.tempSize = 0;
			}
	// Transform the final input block.
	public static byte[] TransformFinalBlock(CryptoAPITransform transform,
										     byte[] inputBuffer,
									  		 int inputOffset,
									  		 int inputCount)
			{
				int blockSize = transform.blockSize;
				byte[] iv = transform.iv;
				IntPtr state = transform.state;
				int offset;
				byte[] tempBuffer = transform.tempBuffer;
				byte[] outputBuffer;
				int tempSize;
				int index;

				// Allocate the output buffer.
				outputBuffer = new byte [inputCount + transform.tempSize];

				// Process as many full blocks as possible.
				index = inputCount - (inputCount % blockSize);
				offset = TransformBlock(transform, inputBuffer,
									    inputOffset, index,
										outputBuffer, 0);
				inputOffset += index;
				inputCount -= index;

				// Flush the first block if we need the extra space.
				tempSize = transform.tempSize;
				if(tempSize > blockSize && inputCount > 0)
				{
					// Decrypt the ciphertext block and XOR with the IV.
					CryptoMethods.Decrypt(state, tempBuffer, blockSize,
										  tempBuffer, 0);
					for(index = blockSize - 1; index >= 0; --index)
					{
						tempBuffer[index] ^= iv[index];
					}

					// Copy the original ciphertext to the IV.
					Array.Copy(tempBuffer, blockSize, iv, 0, blockSize);

					// Copy the plaintext into place.
					Array.Copy(tempBuffer, 0, outputBuffer,
							   offset, blockSize);

					// Advance to the next output block.
					offset += blockSize;

					// Shift the second block down to the first position.
					Array.Copy(tempBuffer, blockSize * 2,
							   tempBuffer, blockSize, blockSize);
					tempSize -= blockSize;
				}

				// Copy the remainder of the data into the temporary buffer.
				Array.Copy(inputBuffer, inputOffset,
						   tempBuffer, tempSize + blockSize, inputCount);
				tempSize += inputCount;

				// "Applied Cryptography" describes Cipher Text Stealing
				// as taking two blocks to generate the short end-point.
				// If we less than one block, then use CFB instead.
				if(tempSize < blockSize)
				{
					// Decrypt the single block in CFB mode.
					CryptoMethods.Encrypt(transform.state2, iv, 0, iv, 0);
					for(index = 0; index < tempSize; ++index)
					{
						outputBuffer[offset + index] =
							(byte)(iv[index] ^ tempBuffer[index + blockSize]);
					}
				}
				else
				{
					// Decrypt the second last ciphertext block.
					CryptoMethods.Decrypt(state, tempBuffer, blockSize,
										  tempBuffer, blockSize);

					// Rebuild the ciphertext for the last block.
					for(index = inputCount; index < blockSize; ++index)
					{
						tempBuffer[blockSize * 2 + index] =
								tempBuffer[blockSize + index];
					}

					// Get the last plaintext block from the second
					// last ciphertext block.
					for(index = inputCount - 1; index >= 0; --index)
					{
						outputBuffer[offset + blockSize + index] =
							(byte)(tempBuffer[blockSize + index] ^
								   tempBuffer[blockSize * 2 + index]);
					}

					// Decrypt the last ciphertext block that we rebuilt.
					CryptoMethods.Decrypt(state, tempBuffer, blockSize * 2,
										  tempBuffer, 0);

					// XOR the block with the IV to get the second
					// last plaintext block.
					for(index = blockSize - 1; index >= 0; --index)
					{
						outputBuffer[offset + index] =
							(byte)(iv[index] ^ tempBuffer[index]);
					}
				}

				// Finished.
				return outputBuffer;
			}
Beispiel #23
0
        // Transform the final input block.
        public static byte[] TransformFinalBlock(CryptoAPITransform transform,
                                                 byte[] inputBuffer,
                                                 int inputOffset,
                                                 int inputCount)
        {
            int    blockSize = transform.blockSize;
            IntPtr state     = transform.state;

            byte[] tempBuffer = transform.tempBuffer;
            byte[] outputBuffer;
            int    offset, index, pad;

            // Allocate a temporary output buffer.
            outputBuffer = new byte [inputCount + blockSize];

            // Push the remaining bytes through the decryptor.  The
            // final block will end up in "transform.tempBuffer".
            offset = TransformBlock(transform, inputBuffer, inputOffset,
                                    inputCount, outputBuffer, 0);

            // Decrypt the final block in "tempBuffer".
            if (transform.tempSize > 0)
            {
                // Decrypt the ciphertext to get the plaintext.
                CryptoMethods.Decrypt(state, tempBuffer, 0,
                                      tempBuffer, 0);

                // Remove padding.
                if (transform.padding == PaddingMode.PKCS7)
                {
                    // Use PKCS #7 padding.
                    pad = tempBuffer[blockSize - 1];
                    if (pad == 0 || pad > blockSize)
                    {
                        pad = blockSize;
                    }
                    Array.Copy(tempBuffer, 0, outputBuffer,
                               offset, blockSize - pad);
                    offset += blockSize - pad;
                    pad     = 0;
                }
                else if (transform.padding == PaddingMode.Zeros)
                {
                    // Strip zeroes from the end of the block.
                    index = blockSize;
                    while (index > 0 && tempBuffer[index - 1] == 0)
                    {
                        --index;
                    }
                    Array.Copy(tempBuffer, 0, outputBuffer,
                               offset, index);
                    offset += index;
                }
                else
                {
                    // No padding, so return the whole block.
                    Array.Copy(tempBuffer, 0, outputBuffer,
                               offset, blockSize);
                    offset += blockSize;
                }
            }

            // Reduce the output buffer size to the final length.
            if (offset != outputBuffer.Length)
            {
                byte[] newout = new byte [offset];
                if (offset != 0)
                {
                    Array.Copy(outputBuffer, 0, newout, 0, offset);
                }
                Array.Clear(outputBuffer, 0, outputBuffer.Length);
                outputBuffer = newout;
            }

            // Finished.
            return(outputBuffer);
        }
Beispiel #24
0
 // Initialize a "CryptoAPITransform" object for CTS decryption.
 public static void Initialize(CryptoAPITransform transform)
 {
     transform.tempBuffer = new byte [transform.blockSize * 3];
     transform.tempSize   = 0;
 }
Beispiel #25
0
        // Transform the final input block.
        public static byte[] TransformFinalBlock(CryptoAPITransform transform,
                                                 byte[] inputBuffer,
                                                 int inputOffset,
                                                 int inputCount)
        {
            int blockSize = transform.blockSize;

            byte[] iv    = transform.iv;
            IntPtr state = transform.state;
            int    offset;

            byte[] tempBuffer = transform.tempBuffer;
            byte[] outputBuffer;
            int    tempSize;
            int    index;

            // Allocate the output buffer.
            outputBuffer = new byte [inputCount + transform.tempSize];

            // Process as many full blocks as possible.
            index  = inputCount - (inputCount % blockSize);
            offset = TransformBlock(transform, inputBuffer,
                                    inputOffset, index,
                                    outputBuffer, 0);
            inputOffset += index;
            inputCount  -= index;

            // Flush the first block if we need the extra space.
            tempSize = transform.tempSize;
            if (tempSize > blockSize && inputCount > 0)
            {
                // Decrypt the ciphertext block and XOR with the IV.
                CryptoMethods.Decrypt(state, tempBuffer, blockSize,
                                      tempBuffer, 0);
                for (index = blockSize - 1; index >= 0; --index)
                {
                    tempBuffer[index] ^= iv[index];
                }

                // Copy the original ciphertext to the IV.
                Array.Copy(tempBuffer, blockSize, iv, 0, blockSize);

                // Copy the plaintext into place.
                Array.Copy(tempBuffer, 0, outputBuffer,
                           offset, blockSize);

                // Advance to the next output block.
                offset += blockSize;

                // Shift the second block down to the first position.
                Array.Copy(tempBuffer, blockSize * 2,
                           tempBuffer, blockSize, blockSize);
                tempSize -= blockSize;
            }

            // Copy the remainder of the data into the temporary buffer.
            Array.Copy(inputBuffer, inputOffset,
                       tempBuffer, tempSize + blockSize, inputCount);
            tempSize += inputCount;

            // "Applied Cryptography" describes Cipher Text Stealing
            // as taking two blocks to generate the short end-point.
            // If we less than one block, then use CFB instead.
            if (tempSize < blockSize)
            {
                // Decrypt the single block in CFB mode.
                CryptoMethods.Encrypt(transform.state2, iv, 0, iv, 0);
                for (index = 0; index < tempSize; ++index)
                {
                    outputBuffer[offset + index] =
                        (byte)(iv[index] ^ tempBuffer[index + blockSize]);
                }
            }
            else
            {
                // Decrypt the second last ciphertext block.
                CryptoMethods.Decrypt(state, tempBuffer, blockSize,
                                      tempBuffer, blockSize);

                // Rebuild the ciphertext for the last block.
                for (index = inputCount; index < blockSize; ++index)
                {
                    tempBuffer[blockSize * 2 + index] =
                        tempBuffer[blockSize + index];
                }

                // Get the last plaintext block from the second
                // last ciphertext block.
                for (index = inputCount - 1; index >= 0; --index)
                {
                    outputBuffer[offset + blockSize + index] =
                        (byte)(tempBuffer[blockSize + index] ^
                               tempBuffer[blockSize * 2 + index]);
                }

                // Decrypt the last ciphertext block that we rebuilt.
                CryptoMethods.Decrypt(state, tempBuffer, blockSize * 2,
                                      tempBuffer, 0);

                // XOR the block with the IV to get the second
                // last plaintext block.
                for (index = blockSize - 1; index >= 0; --index)
                {
                    outputBuffer[offset + index] =
                        (byte)(iv[index] ^ tempBuffer[index]);
                }
            }

            // Finished.
            return(outputBuffer);
        }
	// Transform the final input block.
	public static byte[] TransformFinalBlock(CryptoAPITransform transform,
										     byte[] inputBuffer,
									  		 int inputOffset,
									  		 int inputCount)
			{
				int blockSize = transform.blockSize;
				IntPtr state = transform.state;
				int offset = 0;
				int size, index, pad;
				byte[] outputBuffer;

				// Allocate space for the final block.
				if(transform.padding == PaddingMode.PKCS7)
				{
					size = inputCount + blockSize - (inputCount % blockSize);
				}
				else
				{
					size = inputCount;
					if((size % blockSize) != 0)
					{
						size += blockSize - (inputCount % blockSize);
					}
				}
				outputBuffer = new byte [size];

				// Process full blocks in the input.
				while(inputCount >= blockSize)
				{
					CryptoMethods.Encrypt(state, inputBuffer, inputOffset,
										  outputBuffer, offset);
					inputOffset += blockSize;
					inputCount -= blockSize;
					offset += blockSize;
				}

				// Format and encrypt the final partial block.
				if(transform.padding == PaddingMode.PKCS7)
				{
					// Pad the block according to PKCS #7.
					for(index = 0; index < inputCount; ++index)
					{
						outputBuffer[offset + index] =
							inputBuffer[inputOffset + index];
					}
					pad = blockSize - (inputCount % blockSize);
					while(index < blockSize)
					{
						outputBuffer[offset + index] = (byte)pad;
						++index;
					}

					// Encrypt the block.
					CryptoMethods.Encrypt(state, outputBuffer,
										  offset + index - blockSize,
										  outputBuffer,
										  offset + index - blockSize);
				}
				else if(inputCount > 0)
				{
					// Pad the block with zero bytes.
					for(index = 0; index < inputCount; ++index)
					{
						outputBuffer[offset + index] =
							inputBuffer[inputOffset + index];
					}
					while(index < blockSize)
					{
						outputBuffer[offset + index] = (byte)0x00;
						++index;
					}

					// Encrypt the block.
					CryptoMethods.Encrypt(state, outputBuffer,
										  offset + index - blockSize,
										  outputBuffer,
										  offset + index - blockSize);
				}

				// Finished.
				return outputBuffer;
			}