Example #1
0
        public byte[] TransformFinalBlock(byte[] input, int inputOffset, int count)
        {
            ulong ivLength = this.iv == null ? 0 : (ulong)this.iv.Length;

            uint  result;
            ulong outputSize;

            // Get the required size of the plaintext/ciphertext buffer
            if (this.isEncrypting)
            {
                result = BCryptCore.BCryptEncrypt(this.hKey, input, (ulong)count, IntPtr.Zero, this.iv, ivLength, null, 0, out outputSize, BCryptConstants.BCRYPT_BLOCK_PADDING);
                if (result != 0)
                {
                    throw new SystemException("An error was encountered while retrieving the ciphertext size.");
                }
            }
            else
            {
                result = BCryptCore.BCryptDecrypt(this.hKey, input, (ulong)count, IntPtr.Zero, this.iv, ivLength, null, 0, out outputSize, BCryptConstants.BCRYPT_BLOCK_PADDING);
                if (result != 0)
                {
                    throw new SystemException("An error was encountered while retrieving the plaintext size.");
                }
            }

            byte[] output = new byte[outputSize];

            // No padding is used with authenticatied modes
            // Bypass final block transformation and defer to regular transformation
            if (this.mode == BlockCipherMode.GCM || this.mode == BlockCipherMode.CCM)
            {
                this.TransformBlock(input, inputOffset, output, 0, count);
                return(output);
            }

            ulong pcbResult;

            if (this.isEncrypting)
            {
                result = BCryptCore.BCryptEncrypt(this.hKey, input, (ulong)count, IntPtr.Zero, this.iv, ivLength, output, (ulong)output.Length, out pcbResult, BCryptConstants.BCRYPT_BLOCK_PADDING);
                if (result != 0)
                {
                    throw new SystemException("An error was encountered during encryption.");
                }
            }
            else
            {
                result = BCryptCore.BCryptDecrypt(this.hKey, input, (ulong)count, IntPtr.Zero, this.iv, ivLength, output, (ulong)output.Length, out pcbResult, BCryptConstants.BCRYPT_BLOCK_PADDING);
                if (result != 0)
                {
                    throw new SystemException("An error was encountered during decryption.");
                }
            }

            return(output);
        }
        public static void SetBlockChainingMode(IntPtr hAlgorithmProvider, BlockCipherMode mode)
        {
            string chainingModeValue;

            switch (mode)
            {
            case BlockCipherMode.CBC:
                chainingModeValue = BCryptConstants.BCRYPT_CHAIN_MODE_CBC;
                break;

            case BlockCipherMode.CCM:
                chainingModeValue = BCryptConstants.BCRYPT_CHAIN_MODE_CCM;
                break;

            case BlockCipherMode.CFB:
                chainingModeValue = BCryptConstants.BCRYPT_CHAIN_MODE_CFB;
                break;

            case BlockCipherMode.ECB:
                chainingModeValue = BCryptConstants.BCRYPT_CHAIN_MODE_ECB;
                break;

            case BlockCipherMode.GCM:
                chainingModeValue = BCryptConstants.BCRYPT_CHAIN_MODE_GCM;
                break;

            case BlockCipherMode.Unspecified:
                chainingModeValue = BCryptConstants.BCRYPT_CHAIN_MODE_NA;
                break;

            default:
                throw new ArgumentException("The specified block cipher chaining mode is not recognized.", nameof(mode));
            }

            GCHandle gcChainingModeValue = GCHandle.Alloc(chainingModeValue, GCHandleType.Pinned);

            uint result;

            try
            {
                result = BCryptCore.BCryptSetProperty(hAlgorithmProvider, BCryptConstants.BCRYPT_CHAINING_MODE, gcChainingModeValue.AddrOfPinnedObject(), (ulong)chainingModeValue.Length, 0);
            }
            finally
            {
                gcChainingModeValue.Free();
            }

            if (result != 0)
            {
                throw new SystemException("An error was encountered while setting the cipher chaining mode.");
            }
        }
Example #3
0
        public void TransformBlock(byte[] input, int inputOffset, byte[] output, int outputOffset, int count)
        {
            ulong pcbResult;
            ulong ivLength = this.iv == null ? 0 : (ulong)this.iv.Length;

            if (this.isEncrypting)
            {
                uint result = BCryptCore.BCryptEncrypt(this.hKey, input, (ulong)count, IntPtr.Zero, this.iv, ivLength, output, (ulong)output.Length, out pcbResult, BCryptConstants.BCRYPT_NO_PADDING);
                if (result != 0)
                {
                    throw new SystemException("An error was encountered during encryption.");
                }
            }
            else
            {
                uint result = BCryptCore.BCryptDecrypt(this.hKey, input, (ulong)count, IntPtr.Zero, this.iv, ivLength, output, (ulong)output.Length, out pcbResult, BCryptConstants.BCRYPT_NO_PADDING);
                if (result != 0)
                {
                    throw new SystemException("An error was encountered during decryption.");
                }
            }
        }
Example #4
0
        public BCryptAesTransformer(BlockCipherMode mode, byte[] key, byte[] iv, bool isEncrypting)
        {
            this.mode = mode;

            uint result = BCryptCore.BCryptOpenAlgorithmProvider(out this.hAlgorithmProvider, "AES", null, 0);

            if (result != 0)
            {
                throw new SystemException("An error was encountered while opening the algorithm provider.");
            }

            BCryptHelper.SetBlockChainingMode(this.hAlgorithmProvider, mode);

            result = BCryptCore.BCryptGenerateSymmetricKey(this.hAlgorithmProvider, out this.hKey, null, 0, key, (ulong)key.Length, 0);
            if (result != 0)
            {
                throw new SystemException("An error was encountered while generating a symmetric key.");
            }

            this.iv           = iv;
            this.isEncrypting = isEncrypting;
        }
Example #5
0
 protected virtual void Dispose(bool disposing)
 {
     BCryptCore.BCryptDestroyKey(this.hKey);
     BCryptCore.BCryptCloseAlgorithmProvider(this.hAlgorithmProvider, 0);
 }