Exemplo n.º 1
0
        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);
                }
            }
        }
Exemplo n.º 2
0
        private int DecryptBlocks(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset, bool bufferLastBlock)
        {
            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");

            int decryptedBytes = 0;

            byte[] ciphertext = null;

            //
            // When decrypting, it's possible for us to be called with the final blocks of data in
            // TransformBlock, and then called with an empty TransformFinalBlock.  This means that we always
            // need to keep the last block of data we see in a depad buffer and not decrypt it until the
            // next TransformBlock or TransformFinalBlock is called.  Otherwise, we could end up decrypting
            // the padding bytes on the last call to TransformBlock and passing them out to our caller as
            // plaintext, when in fact we should have stripped them.
            //

            // If the padding cannot be removed, then we don't need to buffer the final block.
            if (!m_paddingMode.CanRemovePadding)
            {
                bufferLastBlock = false;
            }

            // If we've previously saved data to decrypt, we need to do that first.  Otherwise, we need
            // to allocate a buffer to save the last block of the incoming data in.
            if (m_depadBuffer != null)
            {
                byte[] decryptedDepad = BCryptNative.SymmetricDecrypt(m_key, m_iv, m_depadBuffer);
                Buffer.BlockCopy(decryptedDepad, 0, outputBuffer, outputOffset, decryptedDepad.Length);
                decryptedBytes += decryptedDepad.Length;
                outputOffset   += decryptedDepad.Length;
            }

            // If we need to save the last block of data, do that now
            if (bufferLastBlock)
            {
                if (m_depadBuffer == null)
                {
                    m_depadBuffer = new byte[InputBlockSize];
                }

                // Copy the last block of data to the depad buffer, and decrypt the first blocks now.
                ciphertext = new byte[inputCount - m_depadBuffer.Length];
                Buffer.BlockCopy(inputBuffer, inputOffset, ciphertext, 0, ciphertext.Length);
                Buffer.BlockCopy(inputBuffer, inputOffset + inputCount - m_depadBuffer.Length, m_depadBuffer, 0, m_depadBuffer.Length);
            }
            else
            {
                // No depadding is necessary, so we can decrypt the entire input now
                m_depadBuffer = null;
                ciphertext    = new byte[inputCount];
                Buffer.BlockCopy(inputBuffer, inputOffset, ciphertext, 0, ciphertext.Length);
            }

            // Decrypt the input that's not been saved in the depad buffer
            Debug.Assert(ciphertext != null, "ciphertext != null");
            if (ciphertext.Length > 0)
            {
                byte[] plaintext = BCryptNative.SymmetricDecrypt(m_key, m_iv, ciphertext);
                Buffer.BlockCopy(plaintext, 0, outputBuffer, outputOffset, plaintext.Length);
                decryptedBytes += plaintext.Length;
            }

            return(decryptedBytes);
        }