internal BCryptSymmetricCryptoTransform(SafeBCryptAlgorithmHandle algorithm,
                                                byte[] key,
                                                byte[] iv,
                                                PaddingMode paddingMode,
                                                bool encrypting)
        {
            Debug.Assert(algorithm != null, "algorithm != null");
            Debug.Assert(!algorithm.IsClosed && !algorithm.IsInvalid, "!algorithm.IsClosed && !algorithm.IsInvalid");
            Debug.Assert(key != null, "key != null");

            m_algorithm  = algorithm;
            m_encrypting = encrypting;

            m_paddingMode = BlockPaddingMethod.Create(paddingMode,
                                                      BCryptNative.GetInt32Property(algorithm, BCryptNative.ObjectPropertyName.BlockLength));
            m_iv = ProcessIV(iv, BCryptNative.GetInt32Property(algorithm,
                                                               BCryptNative.ObjectPropertyName.BlockLength),
                             BCryptNative.MapChainingMode(BCryptNative.GetStringProperty(algorithm, BCryptNative.ObjectPropertyName.ChainingMode)));
            m_key = BCryptNative.ImportSymmetricKey(algorithm, key);
        }
        internal BCryptAuthenticatedSymmetricCryptoTransform(SafeBCryptAlgorithmHandle algorithm,
                                                             byte[] key,
                                                             byte[] nonce,
                                                             byte[] authenticatedData,
                                                             byte[] tag,
                                                             bool chainingSupported)
        {
            Debug.Assert(algorithm != null, "algorithm != null");
            Debug.Assert(!algorithm.IsClosed && !algorithm.IsInvalid, "!algorithm.IsClosed && !algorithm.IsInvalid");

            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
            if (tag == null)
            {
                throw new ArgumentNullException("tag");
            }

            bool initializationComplete = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                m_algorithm = algorithm;
                m_key       = BCryptNative.ImportSymmetricKey(algorithm, key);

                // Initialize the padding info structure.
                m_authInfo = new BCryptNative.BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO();
                BCryptNative.InitializeAuthnenticatedCipherModeInfo(ref m_authInfo);

                if (nonce != null)
                {
                    m_authInfo.cbNonce = nonce.Length;
                    m_authInfo.pbNonce = Marshal.AllocCoTaskMem(m_authInfo.cbNonce);
                    Marshal.Copy(nonce, 0, m_authInfo.pbNonce, m_authInfo.cbNonce);
                }

                if (authenticatedData != null)
                {
                    m_authInfo.cbAuthData = authenticatedData.Length;
                    m_authInfo.pbAuthData = Marshal.AllocCoTaskMem(m_authInfo.cbAuthData);
                    Marshal.Copy(authenticatedData, 0, m_authInfo.pbAuthData, m_authInfo.cbAuthData);
                }

                if (chainingSupported)
                {
                    m_chainingSupported = chainingSupported;

                    m_authInfo.cbMacContext = tag.Length;
                    m_authInfo.pbMacContext = Marshal.AllocCoTaskMem(m_authInfo.cbMacContext);

                    BCryptNative.BCRYPT_KEY_LENGTHS_STRUCT tagLengths =
                        BCryptNative.GetValueTypeProperty <SafeBCryptAlgorithmHandle, BCryptNative.BCRYPT_KEY_LENGTHS_STRUCT>(
                            algorithm,
                            BCryptNative.ObjectPropertyName.AuthTagLength);

                    m_chainData = new byte[tagLengths.dwMaxLength];
                }
                else
                {
                    m_inputBuffer = new MemoryStream();
                }

                m_authInfo.cbTag = tag.Length;
                m_authInfo.pbTag = Marshal.AllocCoTaskMem(m_authInfo.cbTag);
                Marshal.Copy(tag, 0, m_authInfo.pbTag, m_authInfo.cbTag);

                // Set chaining mode if supported.
                if (CanChainBlocks)
                {
                    m_authInfo.dwFlags |= BCryptNative.AuthenticatedCipherModeInfoFlags.ChainCalls;
                }

                initializationComplete = true;
            }
            finally
            {
                // If we failed to complete initialization we may have already allocated some native
                // resources.  Clean those up before leaving the constructor.
                if (!initializationComplete)
                {
                    Dispose();
                }
            }
        }