public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
        {
            if (inputBuffer == null)
            {
                throw new ArgumentNullException("inputBuffer");
            }
            if (inputOffset < 0)
            {
                throw new ArgumentOutOfRangeException("inputOffset");
            }
            if (inputCount < 0)
            {
                throw new ArgumentOutOfRangeException("inputCount");
            }
            if (inputCount > inputBuffer.Length - inputOffset)
            {
                throw new ArgumentOutOfRangeException("inputCount");
            }

            if (m_encrypting)
            {
                // We need to pad the final block before encrypting it
                byte[] paddedBlock = m_paddingMode.PadBlock(inputBuffer, inputOffset, inputCount);
                if (paddedBlock.Length > 0)
                {
                    return(BCryptNative.SymmetricEncrypt(m_key, m_iv, paddedBlock));
                }
                else
                {
                    return(paddedBlock);
                }
            }
            else
            {
                // We can't decrypt a partial final block
                if (inputCount % InputBlockSize != 0)
                {
                    throw new CryptographicException(Properties.Resources.CannotDecryptPartialBlock);
                }

                // Decrypt all remaining data
                byte[] plaintext       = new byte[inputCount + (m_depadBuffer != null ? m_depadBuffer.Length : 0)];
                int    plaintextLength = DecryptBlocks(inputBuffer, inputOffset, inputCount, plaintext, 0, false);

                // Remove any padding
                return(m_paddingMode.DepadBlock(plaintext, 0, plaintextLength));
            }
        }
        private int EncryptBlocks(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
        {
            Debug.Assert(inputBuffer != null, "inputBuffer != null");
            Debug.Assert(inputOffset >= 0, "inputOffset >= 0");
            Debug.Assert(inputCount >= 0 && inputCount <= inputBuffer.Length - inputOffset, "inputCount >= 0 && inputCount <= inputBuffer.Length - inputOffset");
            Debug.Assert(inputCount % InputBlockSize == 0, "inputCount % InputBlockSize == 0");
            Debug.Assert(outputBuffer != null, "outputBuffer != null");
            Debug.Assert(inputCount <= outputBuffer.Length - outputOffset, "inputCount <= outputBuffer.Length - outputOffset");

            // Pull the input into a stand alone array
            byte[] plaintext = new byte[inputCount];
            Buffer.BlockCopy(inputBuffer, inputOffset, plaintext, 0, plaintext.Length);

            // Do the encryption
            byte[] ciphertext = BCryptNative.SymmetricEncrypt(m_key, m_iv, plaintext);

            // Copy the output to the destination array
            Buffer.BlockCopy(ciphertext, 0, outputBuffer, outputOffset, ciphertext.Length);
            return(ciphertext.Length);
        }
        private byte[] CngTransform(byte[] input, int inputOffset, int inputCount)
        {
            Debug.Assert(m_key != null, "key != null");
            Debug.Assert(!m_key.IsClosed && !m_key.IsInvalid, "!m_key.IsClosed && !m_key.IsInvalid");
            Debug.Assert(input != null, "input != null");
            Debug.Assert(inputOffset >= 0, "inputOffset >= 0");
            Debug.Assert(inputCount >= 0, "inputCount >= 0");
            Debug.Assert(inputCount <= input.Length - inputOffset, "inputCount <= input.Length - inputOffset");

            byte[] inputBuffer = null;
            try
            {
                // Build up a buffer of the only portion of the input we should be transforming
                inputBuffer = input;
                if (inputOffset > 0 || inputCount != input.Length)
                {
                    inputBuffer = new byte[inputCount];
                    Array.Copy(input, inputOffset, inputBuffer, 0, inputBuffer.Length);
                }

                if (m_encrypting)
                {
                    return(BCryptNative.SymmetricEncrypt(m_key, inputBuffer, m_chainData, ref m_authInfo));
                }
                else
                {
                    return(BCryptNative.SymmetricDecrypt(m_key, inputBuffer, this.m_chainData, ref m_authInfo));
                }
            }
            finally
            {
                if (inputBuffer != input)
                {
                    // Zeroize the input buffer if we allocated one
                    Array.Clear(inputBuffer, 0, inputBuffer.Length);
                }
            }
        }