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("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); } } }